等待协程完成,然后再继续使用 C# Unity 函数

问题描述 投票:0回答:3

我正在研究如何让一个单元在 Unity2d 中的网格中移动。我让运动毫无问题地工作。 我希望 MovePlayer 函数等到协程完成后再继续,因此程序将等到玩家完成移动后再发出更多命令。

这是我的代码: 公共类玩家: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;
    }

}
c# coroutine unity-game-engine
3个回答
10
投票

你不能在主线程的函数中等待协程,否则你的游戏将冻结直到你的函数结束。

为什么不在协程结束时调用下一步?

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
}

3
投票

此外,如果这个问题得到回答,有些人无法使用 itectori 的解决方案,所以这是我的解决方案:

你可以做

yield return StartCoroutine(yourCoroutine);

但是在这种情况下你的函数不能返回 void。


0
投票

您可以将这两个调用封装到一个协程中,并使用

yield return
确保它们不会并行运行。

public void MovePlayer(List<Node> path)
{
    StartCoroutine(MovePlayerCoroutine(path));
}

private IEnumerator MovePlayerCoroutine(List<Node> path)
{
    yield return SmoothMovement(path);
    yield return NextSteps();
}

private IEnumerator SmoothMovement(List<Node> path)
{
    ...
}

private IEnumerator NextSteps()
{
    ...
}
© www.soinside.com 2019 - 2024. All rights reserved.