Loops
Loops are one of the most powerful tools in programming. Imagine a game where the entire level can be nuked. When this happens, you'll want to destroy almost everything in the scene. Now, you can do this by deleting each and every object individually in code, one line at a time. If you did this, then a small scene with only a few objects would take just a few lines of code, and this wouldn't be problematic. However, for larger scenes with potentially hundreds of objects, you'd have to write a lot of code, and this code would need to be changed if you altered the contents of the scene. This would be tedious. Loops can simplify the process to just a few lines, regardless of scene complexity or object number. They allow you to repeatedly perform operations on potentially many objects. There are several kinds of loops in C#. Let's see some examples.
The foreach loop
Perhaps, the simplest loop type in C# is the foreach
loop. Using foreach
, you can cycle through every element in an array, sequentially from start to end, processing each item as required. Consider the following code sample 1-6; it destroys all GameObjects
from a GameObject
array:
01 using UnityEngine; 02 using System.Collections; 03 04 public class MyScriptFile : MonoBehaviour 05 { 06 //Array of game objects in the scene 07 public GameObject[] MyObjects; 08 09 // Use this for initialization 10 void Start () 11 { 12 //Repeat code for all objects in array, one by one 13 foreach(GameObject Obj in MyObjects) 14 { 15 //Destroy object 16 Destroy (Obj); 17 } 18 } 19 20 // Update is called once per frame 21 void Update () 22 { 23 } 24 }
Note
Downloading the example code
You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
The foreach
loop repeats the code block {}
between lines 14–17, once for each element in the array MyObjects
. Each pass or cycle in the loop is known as an iteration. The loop depends on array size; this means that larger arrays require more iterations and more processing time. The loop also features a local variable obj
. This is declared in the foreach
statement in line 13. This variable stands in for the selected or active element in the array as the loop passes each iteration, so obj
represents the first element in the loop on the first iteration, the second element on the second iteration, and so on.
Tip
More information on the foreach
loop and its usage in C# can be found at http://msdn.microsoft.com/en-GB/library/ttw7t8t6.aspx.
The for loop
The foreach
loop is handy when you need to iterate through a single array sequentially from start to end, processing each element one at a time. But sometimes you need more control over the iterations. You might need to process a loop backwards from the end to the start, you might need to process two arrays of equal length simultaneously, or you might need to process every alternate array element as opposed to every element. You can achieve this using the for
loop, as shown here:
//Repeat code backwards for all objects in array, one by one for(int i = MyObjects.Length-1; i >= 0; i--) { //Destroy object DestroyMyObjects[i]); }
The following are the comments for the preceding code snippet:
- Here, the
for
loop traverses theMyObjects
array backwards from the end to the start, deleting eachGameObject
in the scene. It does this using a local variablei
. This is sometimes known as anIterator
variable, because it controls how the loop progresses. - The
for
loop line has the following three main parts, each separated by a semicolon character:i
: This is initialized toMyObjects.Length – 1
(the last element in the array). Remember that arrays are zero-indexed, so the last element is alwaysArray Length -1
. This ensures that loop iteration begins at the array end.i >= 0
: This expression indicates the condition when the loop should terminate. Thei
variable acts like a countdown variable, decrementing backwards through the array. In this case, the loop should end wheni
is no longer greater than or equal to0
, because0
represents the start of the array.i--
: This expression controls how the variablei
changes on each iteration of the loop moving from the array end to the beginning. Here,i
will be decremented by one on each iteration, that is, a value of1
will be subtracted fromi
on each pass of the loop. In contrast, the statement++
will add1
.
- During the loop, the expression
MyObjects[i]
is used to access array elements.
Tip
More information on the for
loop and its usage in C# can be found at http://msdn.microsoft.com/en-gb/library/ch45axte.aspx.
The while loop
Both the for
and foreach
loops were especially useful when cycling through an array, performing specific operations on each iteration. The while
loop, in contrast, is useful to continually repeat a specific behavior until a specified condition evaluates to false
. For example, if you must deal damage to the player as long as they're standing on hot lava or continually move a vehicle until the breaks are applied, then a while
loop could be just what you need, as shown in the following code sample 1-7:
01 using UnityEngine; 02 using System.Collections; 03 04 public class MyScriptFile : MonoBehaviour 05 { 06 // Use this for initialization 07 void Start () 08 { 09 //Will count how many messages have been printed 10 int NumberOfMessages = 0; 11 12 //Loop until 5 messages have been printed to the console 13 while(NumberOfMessages < 5) 14 { 15 //Print message 16 Debug.Log ("This is Message: " + NumberOfMessages.ToString()); 17 18 //Increment counter 19 ++NumberOfMessages; 20 } 21 } 22 23 // Update is called once per frame 24 void Update () 25 { 26 } 27 }
Note
ToString
Many classes and objects in Unity have a ToString
function (see line 16 of code sample 1-7). This function converts the object, such as an integer (whole number), to a human-readable word or statement that can be printed to the Console or Debugging window. This is useful for printing objects and data to the console when debugging. Note that converting numerical objects to strings requires an implicit conversion.
The following are the comments for code sample 1-7:
- Line 13 begins the
while
loop with the condition that it repeats until the integer variableNumberOfMessages
exceeds or equals 5 - The code block between lines 15 and 19 is repeated as the body of the
while
loop - Line 19 increments the variable
NumberOfMessages
on each iteration
The result of code sample 1-7, when executed in the game mode, will be to print five text messages to the Unity Console when the level begins, as shown in the following screenshot:
Tip
More information on the while
loop and its usage in C# can be found at http://msdn.microsoft.com/en-gb/library/2aeyhxcd.aspx.
Infinite loops
One danger of using loops, especially while
loops, is to accidentally create an infinite loop, that is, a loop that cannot end. If your game enters an infinite loop, it will normally freeze, perhaps permanently, requiring you to force a quit by terminating the application or even worse, causing a complete system crash! Often, Unity will catch the problem and exit but don't rely on this. For example, removing line 19 of the code sample 1-7 would create an infinite loop because the NumberOfMessages
variable will never increment to a level that satisfies the while
loop condition, thereby causing an exit. The message of this section, then, is first and foremost, "Take care when writing and planning loops to avoid infinite loops." The following is another classic example of an infinite loop that will certainly cause problems for your game, so be sure to avoid them:
//Loop forever while(true) { }
However, believe it or not, there are times when infinite loops are technically what you need for your game under the right conditions! If you need a moving platform to travel up and down endlessly, a magical orb to continually spin round and round, or a day-night cycle to perpetually repeat, then an infinite loop can be serviceable, provided it's implemented appropriately. Later in this book, we'll see examples where infinite loops can be put to good use. Loops are powerful, fun structures, but when coded inappropriately, whether infinite or not, they can be the source of crashes, stalls, and performance issues, so take care. In this book, we'll see good practices for creating loops.