Coroutine: delay transform rotation but start transform movement immediately

Hi,

At the moment I’ve written this script so that when a boolean value is toggled on, I move the camera to a new position and rotation over time.

The problem I’m having is that in the coroutine MoveToPositionOrtho, I want to start the movement immediately, but have a delay of 2 seconds before rotating the camera.
But I still want the movement and rotation to finish at the same time.

I can’t work out how I need to write this, because if I move the transform.position above the line yield WaitForSeconds this stops the movement during the delay.

Does anyone have any pointers on how I should go about scripting this - is it possible to have a delay only affecting the rotation and not the movement?

using UnityEngine;
using System.Collections;

[RequireComponent (typeof(MatrixBlender))]
public class PerspectiveSwitchFinal : MonoBehaviour {
	
	private Matrix4x4   ortho, perspective;
	public float fov = 60f,
	near = 0.3f,
	far  = 1000f,
	orthographicSize = 50f;
	private float aspect;
	private MatrixBlender blender;
	public bool orthoOn;
	
	public GameObject cameraMain;
	
	private float degree;
	private float angle;
	
	
	void Start()
	{
		aspect = (float) Screen.width / (float) Screen.height;
		ortho = Matrix4x4.Ortho(-orthographicSize * aspect, orthographicSize * aspect, -orthographicSize, orthographicSize, near, far);
		perspective = Matrix4x4.Perspective(fov, aspect, near, far);
		GetComponent<Camera>().projectionMatrix = ortho;
		orthoOn = true;
		blender = (MatrixBlender) GetComponent(typeof(MatrixBlender));	
		
	}



	public void orthoToggle(bool on)
	{
		orthoOn = on;	

		if (orthoOn != true)
		{
			blender.BlendToMatrix(perspective, 12f);
			degree = 6f;
			StopAllCoroutines();
			StartCoroutine (MoveToPositionPersp (new Vector3(0,0.5f,-12f), 8f, 0f));
		}
		
		
		if (orthoOn == true)
		{
			blender.BlendToMatrix(ortho, 6f);
			degree = 45f;
			StopAllCoroutines();
			StartCoroutine ( MoveToPositionOrtho (new Vector3(0,5.5f,-3.6f), 2f, 4f)); //4 3.2
		}

	}
	
	
	
	public IEnumerator MoveToPositionOrtho(Vector3 position, float timeToMove, float waitTime)
	{
		yield return new WaitForSeconds(waitTime);
		
		
		var currentPos = transform.position;
		var currentPosRotate = transform.rotation;
		var t = 0f;
		
		
		while(t < 1)
		{
			t += Time.deltaTime / timeToMove;
			
			transform.position = Vector3.Lerp(currentPos, position, t);
			
			angle = Mathf.LerpAngle(transform.rotation.x, degree, Time.deltaTime);
			transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(degree, 0, 0), t);
			
			yield return null;
		}
	}
	
	
	
	
	
	public IEnumerator MoveToPositionPersp(Vector3 position, float timeToMove, float waitTime)
	{
		yield return new WaitForSeconds(waitTime);
		
		var currentPos = transform.position;
		var currentPosRotate = transform.rotation;
		var t = 0f;
		
		
		while(t < 1)
		{
			t += Time.deltaTime / timeToMove;
			transform.position = Vector3.Lerp(currentPos, position, t);
			
			angle = Mathf.LerpAngle(transform.rotation.x, degree, Time.deltaTime);
			transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(degree, 0, 0), t);
			
			yield return null;
		}
	}
	
}

Any help would be so much appreciated!

Best,
Laurien

Calculate another ‘t’ that for example starts ‘2 seconds below zero’ , increment it proportionally faster so it reaches 1 at the same time with ‘t’ and use that value as ‘t’ for rotation.

const float delay = 2f;
var t = 0f;
var ratio = delay/(timeToMove - delay);// ratio of delay vs. time left for rotation
var t2 = -ratio;
while(t < 1)
{
    t += Time.deltaTime / timeToMove;
    t2 += Time.deltaTime / (timeToMove/(1 + ratio));
    ...
   transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(degree, 0, 0), t2);
}

On my mobile. Not sure about the math coz i couldn’t test it.

Another way of course would be to use separate coroutines for movement & rotation.

You must separately handle situations where timeToMove is less than delay.

you must use better in the coroutine that:

IEnumerator Counter()
{
    yield return new WaitForSeconds(2);     //Anything after this line is going to be called
    //here goes your code                   //after 2 seconds
}