- Home /
Inconsistency with For Loop
Hi,
I have a question regarding for loops. Here's a snippet of code:
public var heart : GameObject;
public var maxHeart : int;
public var i : int;
function Update() {
for (i=0; i<maxHeart; i++) {
instantiate(heart,Vector3(i*20,0,0),Quaternion.Identity);
}
}
In the inspector, I set the maxHeart to 4. When I click play the i stops at 4 but instantiates non stop in the scene. Why is it behaving like that when the condition of the loop is if it's less than maxHeart?
So I replace the for loop with while loop instead:
while(i < maxHeart) {
i++;
instantiate(heart,Vector3(i*20,0,0),Quaternion.Identity);
}
and this bloody works. I would like to know why the for loop is behaving like this when both of the functions are similar.
The for
loop sets "i=0" at the beginning all the time. In the while
loop, this doesn't happen, so i is always larger than maxHeart when the loop is reached again.
As a side note, it's better practice if you keep variables local where possible. Don't declare "i" outside the functions it's being used in.
Eric is right. What you would normally do for something of the nature you want is use this code in Start()
because you want them instantiated at the beginning, but only once.
Answer by Bunny83 · Jun 18, 2012 at 09:53 AM
The for loop has 3 parts:
for (PART1; PART2; PART3)
PART1 is executed one time when the for loop is entered, this is usually used to initialize a variable like you did.
PART2 is a condition which is checked reight before each iteration. If it's false the for loop is terminated.
PART3 is executed right after each iteration. It's used to prepare the next iteration step.
You problem is that you set the variable i to 0 each time you execute the code (which is every frame since you have it in Update).
Btw, You really shouldn't use a public instance variable as for loop variable. for loops usually use local variables. Also the name "i" is ok as local temporal variable in a vor loop, but as instance variable the name doesn't make much sense.
Thanks very much. I thought the initialisation/part 1 is always called once. Didn't know function update resets it to 0 everytime. Also, the reason we declared the vars outside of the scope is so we can change it in the inspector. If we do it local, does that mean we have to hard code the values? Is it not good practise if we change it at the inspector?
Thanks again :)
Note you can also "cheat" by leaving any of the PARTs empty. But that's rather hackish:
for (; i<maxHeart; i++) // skip initialization
for (;;) // infinite loop
@Wolfram: It's not even cheating ;) It has those three sections, what you do with it is up to you. It's also possible to iterate through a linked list like this:
for (item = first; item != null; item = item.next)
@Hakimo: No, you got me wrong. maxHeart should be declared outside. It also has a good name. I was talking about the variable "i". It doesn't have any meaning outside of the forloop and also doesn't need really need to keep it's value.
If you want to execute the for loop once, you should call it in Start() and not in Update ;) It makes no sense to execute the for loop every frame with a condition that should only be true for the first frame.
Answer by whydoidoit · Jun 18, 2012 at 09:49 AM
Because the for loop is setting i back to 0 every Update and the while loop isn't.