- Home /
FixedUpdate loop vs WaitForFixedUpdate loop inside coroutine
I've written a script to detect the speed of the ball and force it to stop under some condition. I've tried two approach about this case. First, I used FixedUpdate and second, I use coroutine.
//fixedupdate void FixedUpdate () { //check some conditions
if (Ball.CurrentBallVelocity.magnitude != 0)
Ball.Stop(); //rigidbody.sleep()
}
//coroutine while (true) { //check some conditions
if (Ball.CurrentBallVelocity.magnitude != 0)
Ball.Stop(); //rigidbody.sleep()
else break;
yield return new WaitForFixedUpdate();
}
The result is that fixedUpdate always works. But coroutine doesn't work every time and the code gets stuck in infinite loop. I use debug.log and discover that the ball velocity in coroutine loop is just only near zero such as 10E-7 which can't terminate the loop. So I change if condition to (Ball.CurrentBallVelocity.magnitude > Physics.sleepVelocity)
instead. It can finally exit the loop but the result is strange. Because in each loop of coroutine the ball velocity is decrease gradually. (sample 5.874 -> 4.325 -> 3.546 ...) I don't understand why the ball velocity inside coroutine in next loop doesn't change to 0 immediately after I use rigidbody.sleep()
in previous loop. This problem happens sometimes but fixedupdate doesn't have this problem at all. So I decide to use fixedupdate for this case. But I want to ask what is the problem here?
Note that, I try to use coroutine because I've used it to implement another parts of the code. So I try to use this case inside coroutine too.
Answer by Mike 3 · Jul 10, 2010 at 09:21 PM
Why are you stopping the coroutine if the ball is moving? Surely it'll work very differently to the FixedUpdate version which goes every fixed update.
If you're calling the coroutine constanty, then that'll be another reason it's screwy
Either way - the coroutine version should work fine when coded correctly
It is in the main coroutine loop (start coroutine inside another coroutine). I want to code a series of consecutive event. event1 -> event2 -> event3 etc. Each event may has its own loop or just yield waitforseconds.
It still sounds like your fixedupdate and coroutine handle very differently though
I can finally fix it. I only need to use startcoroutine without yield return. So that the code will check condition in parallel and has the same result like in fixedupdate. :)
That does sound better indeed - just make sure you're not having multiple versions of the same coroutine running if you're doing that
Answer by qJake · Jul 10, 2010 at 05:37 PM
Update() is unreliable for physics and velocity calculations because it does not have a set time interval. Update() could take 5ms or it could take 500ms, and you can't do physics calculations in that environment.
From the FixedUpdate() page:
FixedUpdate should be used instead of Update when dealing with Rigidbody. For example when adding a force to a rigidbody, you have to apply the force every fixed frame inside FixedUpdate instead of every frame inside Update.
But coroutine doesn't run in update(). That's why I use WaitForFixedUpdate() in order to wait for next physics calculation. Can't this code work the same as in fixedupdate?