# Start Coroutine after other has finished

Hi, I’m working on 2d ship game and I’m trying to get my ship to rotate and then move after having finished rotating.
In order to make the rotation happen over time I’m using a while loop inside a coroutine and I’m also using another coroutine to make the ship move but I don’t want the ship to start moving before its finished rotating.
Here is my code:

``````void Update () {
//stuff
StartCoroutine(RotateToTarget());
//isRotatingToTarget = false; pointless since the coroutine wouldn't have finished rotating
//StartCoroutine (MoveToTarget()); If I add this here it doesn't wait for the rotation to finish
}

IEnumerator RotateToTarget(){
while(transform.rotation != rotationToTarget)
{
transform.rotation = Quaternion.Lerp(transform.rotation, rotationToTarget , Time.deltaTime);
this.isRotatingToTarget = (transform.rotation != rotationToTarget);
yield return null;
}
isRotatingToTarget = false;
print ("Can move to target");
StartCoroutine (MoveToTarget()); //this never gets excecuted

}

IEnumerator MoveToTarget(){
if (!isMovingToTarget && !isRotatingToTarget){
while(transform.position.x != target.x && transform.position.y != target.y)
{
isMovingToTarget = true;
transform.position  = Vector2.MoveTowards(transform.position, target, Time.deltaTime*movementSpeed);

yield return null;
}
this.isMovingToTarget = false;
}
``````

I think it is because the comparison statement (transform.rotation != rotationToTarget) always returns true.

It would be better to compare 2 Quaternions using Quaternion.Angle(). You can check out the explanation at http://docs.unity3d.com/ScriptReference/Quaternion-operator_eq.html

So, you can use Quaternion.Angle() to get the angle between 2 quaternions, then you can check whether the angle is below some small threshold.

``````float rotationThreshold = 0.1f;
bool isClosedToTargetRotation = Quaternion.Angle(transform.rotation, rotationToTarget) < rotationThreshold;
``````

Also, due to floating point imprecision, it is not recommended to compare floats using the equal operator. So, to check whether 2 positions are same, it would be better to compare the distance between them.

``````float distanceThreshold = 0.1f;
bool isClosedToTargetPosition = Vector3.Distance(transform.position, target.position) < distanceThreshold;
``````

I wouldn’t use a coroutine for any of this. All you need is, in Update:

``````if (isRotatingToTarget) {
transform.rotation = Quaternion.Lerp(transform.rotation, rotationToTarget , Time.deltaTime);
isRotatingToTarget = (transform.rotation != rotationToTarget);
if (!isRotatingToTarget) isMovingToTarget = true;
} else if (isMovingToTarget) {
transform.position  = Vector2.MoveTowards(transform.position, target, Time.deltaTime*movementSpeed);
if (transform.position.x == target.x && transform.position.y == target.y) isMovingToTarget = false;
}
``````

The code in your question starts the RotateToTarget coroutine on every Update(). This stacks up Coroutine calls. So if your movement script would take 5 seconds to complete and your app is running at 60 fps, you have 300 coroutine running that may be accelerating the process or fighting with each other, or simply taking resources. Coroutines work well when you want independent piece of work to run without interference. If the target will be moving so this code as to reacquire it, then consider using Update() as @Pyrian suggests.

As for not completing the rotation, the issue is this line:

``````transform.rotation = Quaternion.Lerp(transform.rotation, rotationToTarget , Time.deltaTime);
``````

The way this form of Lerp works is to walk the approximately the same fraction of the remaining distance to the goal each frame. Since the distance is shrinking, the same fraction represents smaller and smaller rotations. The result is an eased movement. But the problem is that it takes a very long time to complete…and only completes due to floating point imprecision and perhaps some slop built into rotation comparison. It like the old adage, “how many days will it take to reach my goal if I walk half the distance each day.” The answer is infinite…you never reach your goal. A solution is the one @YWord suggests…to use an angle threshold.

Chaining coroutines or using flags will work for what you want here, but there is an alternate. You can use ‘yield’ with coroutines. Here a demonstration rewrite of your code. It may not be a perfect fit since I don’t have all your code, nor the context where it will be used.

``````using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour {

public Transform target;
public float rotationSpeed = 5.0f;
public float movementSpeed = 2.25f;

private bool isMoving = false;

void Update () {
if (Input.GetKeyDown (KeyCode.Space)) {
StartCoroutine(RotateThenMove());
}
}

IEnumerator RotateThenMove() {
if (isMoving) {
yield break;
}

isMoving = true;
yield return StartCoroutine(RotateToTarget());
yield return StartCoroutine(MoveToTarget());
isMoving = false;
}

IEnumerator RotateToTarget(){
Quaternion rotationToTarget = Quaternion.LookRotation(target.position - transform.position);
while(Quaternion.Angle(transform.rotation,rotationToTarget) > 0.5f) {
transform.rotation = Quaternion.Slerp(transform.rotation, rotationToTarget , Time.deltaTime * rotationSpeed);
yield return null;
}
}

IEnumerator MoveToTarget() {
while(transform.position != target.position) {
transform.position  = Vector3.MoveTowards(transform.position, target.position, Time.deltaTime*movementSpeed);
yield return null;
}
}
}
``````

Although starting the second coroutine in the first coroutine should work (I think), you can use a ‘flag’. Note this will only work if “Can move to target” prints successfully. If it doesn’t, see the paragraph at the end of this solution.

``````private bool canMoveToTarget = false;
``````if(canMoveToTarget) StartCoroutine(MoveToTarget());