- Home /
unity bug??? while loop is satisfied, but doesn't quit
Hi,
I call this coroutine every 0.01f second for a finite number of times (40):
IEnumerator MoveOutLeft(int _i)
{
float smoothlerp = 0;
float toPos = -5;
Vector3 fromPos1 = ChckPntList [_i].transform.localPosition;
Vector3 fromPos2 = ChckPntList [_i+2].transform.localPosition;
while (ChckPntList[_i].transform.localPosition.x > toPos)
{
ChckPntList [_i].transform.localPosition = Vector3.Lerp (fromPos1, new Vector3(toPos, ChckPntList [_i].transform.localPosition.y, 0), (smoothlerp += Time.deltaTime) * 3f);
ChckPntList [_i+2].transform.localPosition = Vector3.Lerp (fromPos2, new Vector3(toPos, ChckPntList [_i+2].transform.localPosition.y, 0), (smoothlerp += Time.deltaTime) * 3f);
print ("left " + _i + " position " + ChckPntList [_i].transform.localPosition + " toPos " + toPos);
yield return null;
}
}
the coroutine does what it's supposed to for 39 members but once it reaches the last one, it just never quits and keeps printing out my debug message.
From the message I can see that the lerp reached its destination but for some reason the loop doesn't exit. Moreover, if I do a debug and go step by step for all 40 members, then the while loop doesn't get stuck. But if I run the game without a debugger attached, this message keeps printing out.
This algorythm was working fine yesterday, then Unity decided to screw my entire project with its occasional 999+ errors/missing scripts and I had to revert to the older project where I copied my code (not the script file, a copied the code itself).
Today it doesn't work anymore, resulting in this weird behavior. When I print while
's condition it says false and keeps going. I have Unity 4.6.3p3.
What do I do?
Is there anything else that changes the value of ChckPntList[_i].transform.localPosition.x
?
If your logging at line 12 shows values, twice in a row, that should prevent the while loop from continuing, then one possibility is that something else is changing a value while your while loop has yielded (after the logging).
You could test this by repeating the logging, after the yield.
Answer by Bigproblem01 · Mar 17, 2015 at 07:40 PM
After several hours of investigating and cursing I did find the problem. It was partly my fault outside of the code mentioned above and partly still unexplained behavior of Unity. It's really complicated to explain in details what was happening but I'll still try to summarize for others because the bug was kind of tough to find since what was visually happening didn't really represent what was going on in code (and I couldn't catch it with print's or debug either).
In short, two while
functions were trying to pull an object to their sides (the other Coroutine, "MoveOutRight", is similar to this one). My mistake was that they shouldn't have affected the same objects but because I overlooked it, did.
Now the still unexplained part is, visually, these objects should've moved back and forth, or at least blink or something - instead they stayed on either side, their position unchanged. Now as I said earlier, the coroutines' conditions where showing false, but they were still running. I get that maybe during one frame the condition wasn't met anymore and before the code could reach that part on the next frame, the other coroutine affected it and made the condition true again. But in this case, one of them should've overpowered the other and stop, and then the other one would stop as well no?
Also, another unresolved mystery is - if I ran the code with debug, looking at these coroutines, they'd stop as I expected them to and all was well, but when run without the debugger they'd run constantly. I'm sure there're explanations for these things, I'm just not knowledgeable enough apparently to be aware of them. If anyone is, I'm all ears.
Answer by tanoshimi · Mar 17, 2015 at 03:18 PM
You're using Lerp incorrectly. Lerp(a,b,c) returns a value c fraction of the distance from a to b. You've written:
ChckPntList [_i].transform.localPosition = Vector3.Lerp (fromPos1, new Vector3(toPos, ChckPntList [_i].transform.localPosition.y, 0), (smoothlerp += Time.deltaTime) * 3f);
So your while loop will neover break unless (smoothlerp + Time.deltaTime ) *3 is >= 1, which I guess it never is.
Time.deltaTime is constantly increasing and thus smoothlerp will most definitely become one. There is nothing wrong with using lerp this way, what it does is it gives you an even movement from a to b ins$$anonymous$$d of a nonuniform one which is achieved by inputing current location ins$$anonymous$$d of a fixed a
and putting Time.deltaTime as the third argument.
@Bigproblem01 I know what you meant, but Time.deltaTime is not constantly increasing!
smoothLerp is always increasing (because Time.deltaTime is always positive), and the rest of your argument follows.
Yeah I put it the wrong way, of course Time.deltaTime doesn't increase, I meant my smoothlerp does because Time.deltaTime is added to it on every frame, thanks for correction
Your answer
Follow this Question
Related Questions
GUI inside a While Loop 1 Answer
Quaternion.Slerp issue 1 Answer
playerID does not exist in current context? 3 Answers
Nothing happening after WaitForSeconds C# 2 Answers
Iterator variable not increasing. 1 Answer