Rotating Object by X Degree Once Every Y Seconds

Here’s my script that sort of does what the title says:

public class RotateXDegEveryYSec : MonoBehaviour {

	public float rotateDegree;      // amount of rotation
	public float rotateInterval;     // how long to pause between each rotation
	private float rotateTime = 1f;      // duration of each rotation

	void Start() {
		StartCoroutine(RotateObject(Vector3.right * rotateDegree, rotateTime));
	}

	IEnumerator RotateObject(Vector3 byAngles, float inTime) { 
		var fromAngle = transform.rotation;
		var toAngle = Quaternion.Euler(transform.eulerAngles + byAngles);
		while (true) {
			yield return new WaitForSeconds(rotateInterval);
			for (var t = 0f; t <= 1; t += Time.deltaTime/inTime) {
				transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t);
				yield return null;
			}
		}
	}
}

I said “sort of” because the object rotation works as intended with the only issue being that the object resets to the initial angle/position every time it rotates. And just for your info, I’m rotating my object by 90 degree every 2 seconds.

I can see the issue is probably due to the fact that fromAngle and toAngle get reset whenever the object rotates, so I tried modifying the code as follows:

IEnumerator RotateObject(Vector3 byAngles, float inTime) { 
	var fromAngle = transform.rotation;
	var toAngle = Quaternion.Euler(transform.eulerAngles + byAngles);
	while (true) {
		yield return new WaitForSeconds(rotateInterval);
		for (var t = 0f; t <= 1; t += Time.deltaTime/inTime) {
			transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t);
			yield return null;
		}
		fromAngle = transform.rotation;
		toAngle = Quaternion.Euler(transform.eulerAngles + byAngles);
		}
	}
}

With the above modded code, the second rotation picks up correctly where the first rotation has ended, but the third rotation rotates the object backward! What am I doing wrong or missing?

I could do this using Animator Controller, but I thought this could be done fairly easily just using script. I hope I’m right.

If you think about rotation speed rather than “angles per second” (which is rotation speed, btw), then it comes together nicely. It’s also easier if you break it down in angle-axis rotation.

This worked okay for me:

public class Test : MonoBehaviour
{
    // Use this for initialization
    void Start()
    {
        StartCoroutine(RotateObject(90, Vector3.right, 2));
    }

    IEnumerator RotateObject(float angle, Vector3 axis, float inTime)
    {
        // calculate rotation speed
        float rotationSpeed = angle / inTime;

        while (true)
        {
            // save starting rotation position
            Quaternion startRotation = transform.rotation;

            float deltaAngle = 0;

            // rotate until reaching angle
            while (deltaAngle < angle)
            {
                deltaAngle += rotationSpeed * Time.deltaTime;
                deltaAngle = Mathf.Min(deltaAngle, angle);

                transform.rotation = startRotation * Quaternion.AngleAxis(deltaAngle, axis);

                yield return null;
            }

            // delay here
            yield return new WaitForSeconds(1);
        }
    }
}

@Arkaid - First of all, thanks for the response. I tested your code and it seems that the script makes the object rotate continuously.

I’m sorry if I wasn’t clear in my initial post, but I needed the object to rotate at a given angle (90 degree in my earlier scenario), then pause for the specified amount of time (e.g., 3 seconds), and rotate for another 90 degree, then pause… and so on.

Lastly, I tried modifying your code to achieve that pause between rotation segments but hasn’t been able to nail it so far.