Myk Willis Myk Willis - 1 year ago 72
C# Question

Unexpected control flow in Unity coroutine (detecting completion)

I have a script attached to a Unity 5 GameObject that rotates the object by a fixed amount when a user clicks a button. The rotation is done in a coroutine to allow it to happen smoothly over time.

I want to block the user from performing another rotation of the same object until the first is done. To do this, I've added an

boolean that is set to true when the coroutine starts, and to false when the coroutine has completed the rotation. The code is as follows:

using UnityEngine;
using System.Collections;

public class ObjectScript : MonoBehaviour {

private bool isRotating = false;

/* Rotate the object 90 degrees around the x axis centered on the origin */
IEnumerator RotateObject() {
isRotating = true;

var updateRotation = 0.0f; // amount to rotate this tick
for (var totalRotation = 0.0f; totalRotation <= 90.0f; totalRotation += updateRotation) {
updateRotation = 90.0f * (Time.deltaTime / 0.5f);
if (totalRotation + updateRotation > 90.0f) {
updateRotation = 90.0f - totalRotation;
transform.RotateAround (, Vector3.right, updateRotation);
yield return null;

isRotating = false; // This line is never reached

void Update () {
if (Input.GetKeyDown(KeyCode.X) && !isRotating) {
StartCoroutine (RotateObject());

My issue is that the
isRotating = false
line is never reached, so
is left set to
, even after the coroutine has finished rotating the object. (I've checked this by placing debug breakpoints on the line, which are never hit). So once the object has been rotated one time, it will never rotate again.

Why does control never get to the line outside of the loop body?

Answer Source

updateRotation = 90.0f - totalRotation;

=> totalRotation + updateRotation = 90

Every time totalRotation + updateRotation > 90.0f you reassign the updateRotation so that next iteration totalRotation + updateRotation = 90

=> totalRotation <= 90.0f is nerver false