Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for a coroutine to finish before moving on with the function C# Unity

I was working on making a unit move through a grid in Unity2d. I got the movement to work without problems. I would want the function MovePlayer to wait until the coroutine is finished before moving on, so the program will wait until the player has finished the movement before issuing more orders.

Here is my code: public class Player : MonoBehaviour {

public Vector3 position;
private Vector3 targetPosition;

private float speed;

void Awake ()
{
    speed = 2.0f;
    position = gameObject.transform.position;
    targetPosition = position;
    GameManager.instance.AddPlayerToList(this);                     //Register this player with our instance of GameManager by adding it to a list of Player objects. 
}

//Function that moves the player, takes a list of nodes as path
public void MovePlayer(List<Node> path)
{
    StartCoroutine(SmoothMovement(path));
    //Next step should wait until SmoothMovement is finished
}

private IEnumerator SmoothMovement(List<Node> path)
{
    float step = speed * Time.deltaTime;

    for (int i = 0; i < path.Count; i++)
    {
        targetPosition = new Vector3(path[i].coordinatesX, path[i].coordinatesY, 0f);

        float sqrRemainingDistance = (transform.position - targetPosition).sqrMagnitude;

        while (sqrRemainingDistance > float.Epsilon)
        {
            transform.position = Vector3.MoveTowards(transform.position, targetPosition, step);
            sqrRemainingDistance = (transform.position - targetPosition).sqrMagnitude;
            yield return null;
        }

        position = transform.position;
    }

}
like image 930
Paco Martos Triguero Avatar asked Jun 04 '17 22:06

Paco Martos Triguero


People also ask

How do you wait until coroutine is done?

To wait for a coroutine to finish, you can call Job. join . join is a suspending function, meaning that the coroutine calling it will be suspended until it is told to resume. At the point of suspension, the executing thread is released to any other available coroutines (that are sharing that thread or thread pool).

How do you make a coroutine wait for another coroutine?

If you want to wait for one coroutine till it finishes, you can put yield return Coroutine1(); at first line in the body Coroutine2 and put the rest of the code after that, this way the Coroutine2 will wait for Coroutine1 till its done, then it will proceed with the rest of the code.

Can you pause a coroutine?

The informative description below, straight from Unity's documentation, shows that a coroutine can suspend it's execution, until the given yield instruction finishes. Basically, scripts run from top to bottom with no pause, but a coroutine gives the ability to pause and wait for instructions before moving on.

Does yield break stop a coroutine?

Simply adding the yield break statement will end a Coroutine before it's finished.


1 Answers

You can not wait for a coroutine in a function in the main thread, otherwise your game will freeze until your function ends.

Why don't you call your next step at the end of your coroutine?

private IEnumerator SmoothMovement(List<Node> path)
{
    float step = speed * Time.deltaTime;

    for (int i = 0; i < path.Count; i++)
    {
        targetPosition = new Vector3(path[i].coordinatesX, path[i].coordinatesY, 0f);

        float sqrRemainingDistance = (transform.position - targetPosition).sqrMagnitude;

        while (sqrRemainingDistance > float.Epsilon)
        {
            transform.position = Vector3.MoveTowards(transform.position, targetPosition, step);
            sqrRemainingDistance = (transform.position - targetPosition).sqrMagnitude;
            yield return null;
        }

        position = transform.position;
    }
    //Next Step
}
like image 169
itectori Avatar answered Oct 10 '22 07:10

itectori