Odd issue with yield and rotation

I’ve been trying to do a very simple turn around function that could be yielded to until it’s complete and it’s confusing me terribly.

function RotateByAmount(angle : float, speed : float)
{
	print("RotateByAmount called! angle: " + angle + "  speed: " + speed);
	
	var startRotation : float = droppingUnit.transform.eulerAngles.y;
	var currRotation : float = 0;

	while(currRotation < angle)
	{
		currRotation = Mathf.Abs(droppingUnit.transform.eulerAngles.y - startRotation);
		print("currRotation: " + currRotation + " startRotation: " + startRotation + " euler.Y: " + droppingUnit.transform.eulerAngles.y);
		droppingUnit.transform.eulerAngles.y += speed * Time.deltaTime;
		
		yield;
	}
	
	return;
}

So in my head this should work fine, the current rotation is checked to see whether it’s more than the angle and if it is, it should stop. The yield should just resume at the end of the while loop and thus restart if the condition is met. This actually works fine if I call the function without yielding to it, but whenever I do “yield RotateByAmount()” it has the most bizarre behaviour.

The console outputs show that not only is it increasing the current rotation upwards but with random jumps and high and low values all over the place, the startRotation variable changes too, which it should never do after it’s been declared which should be before the loop doing the yielding.

I thought I understood co-routines but apparently not, what am I doing wrong?

Also as a side note I understand there is Ani.Mate and so on that can do this for me but i’d rather know the logic behind how yield works.

edit: Instead of yielding to the RotateByAmount I tried yielding afterwards for the estimated time it should take, this caused it to have more strange behaviour with the rotation never stopping.

The Do() function that calls and yields to RotateByAmount is called from the Update() function and from what I understand that makes latent functions operate differently for some reason. The documentation on yielding is remarkably sparse for such an important feature.

I think you got coroutines a bit confused. yield is used inside coroutines to stop the execution of the coroutine until a certain criteria is met (next frame, time etc). You don’t yield a coroutine. You simply call the coroutine and it will execute asynchronously.

i.e. “yield RotateByAmount();” is wrong. You should ever only use a plain yield or together with the Wait* classes.

Also, when trying to start a coroutine inside Update() you have to make sure that the coroutine is only started once. Update() is called each frame and if you’re not careful then you end up starting a new coroutine each frame. They quickly add up, interfere with each other and lead to strange behavior like you are seeing.

I use ‘yield coroutine()’ and it works great. Why is this wrong?

From what I can tell (and have been told by others) it simply waits for the coroutine() to complete before proceeding onwards.

In response to the OP check this thread out

http://forum.unity3d.com/viewtopic.php?t=27272

You may benefit from setting a rotation rate and storing the starting and target rotations like described in that thread.