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.