Quaternion.Slerp in a coroutine

Hi, I’m having an issue with the timing of a rotation. I have a coroutine which translates an object and at the same time I want to rotate it smoothly for as long as it’s moving.

	public IEnumerator MoveToPosition (Vector3 newLocalTarget, float time)
{
	float elapsedTime = 0.0f;
	Vector3 startingPosition = transform.localPosition;

	Quaternion targetRotation =  Quaternion.Euler ( new Vector3 ( 0.0f, 0.0f, 200.0f ) );
		
	while (elapsedTime < time) {
	 	transform.localPosition = Vector3.Lerp (startingPosition, newLocalTarget, (elapsedTime / time)   );	
		
		// Rotations
		transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation,  (elapsedTime / time )  );
 
		elapsedTime += Time.deltaTime;
		yield return new WaitForEndOfFrame ();
	}
	Debug.Log ("Translation and rotation done! ");
	yield return 0;
}

The translation works as expected. However, the rotation rotates to the desired angle, but finishes rotating around half the time it takes the object to translate. Ideally I want the rotation and translation to end at the same time. I’ve tried using Quaternion.Lerp in place, but the same problem exists. Can anyone spot the issue? Is there any other way so the rotation completes at the same time as the translation?

Many thanks

You should have a startingRotation variable to tell what’s the initial rotation. You should also move the elapsedTime increment to the beginning of the while to ensure that the final position/rotation will be reached before the while ends:

    ...
    Vector3 startingPosition = transform.localPosition;
    Quaternion startingRotation = transform.rotation; // have a startingRotation as well
    Quaternion targetRotation =  Quaternion.Euler ( new Vector3 ( 0.0f, 0.0f, 200.0f ) );
    while (elapsedTime < time) {
       elapsedTime += Time.deltaTime; // <- move elapsedTime increment here
       transform.localPosition = Vector3.Lerp (startingPosition, newLocalTarget, (elapsedTime / time)   );  
       // Rotations
       transform.rotation = Quaternion.Slerp(startingRotation, targetRotation,  (elapsedTime / time)  );
       yield return new WaitForEndOfFrame ();
    }
    ...

NOTE: You’re using localPosition, but not localRotation. Is this an intended feature? Mixing local and non-local position/rotation may give weird results.

try putting just the elapsedTime in the Lerp and Slerp instead of (elapsedTime / time)
and to get a linear movement on the translation, use transform.localPosition where starting position is