c# - 让循环等待 Action 完成

标签 c# loops unity3d coroutine

我在 Unity3d 中工作(这更像是一个 C# 问题,所以我怀疑这是一个问题)。我正在研究一种运动系统,就像您在《文明》中看到的那样。我有一个循环设置,这样你每转一圈就可以移动 2 个方格。这很好用。我点击 10 个街区外的一个方 block ,需要转 5 圈才能到达那里。现在我正在尝试让 pawn 在 block 之间进行 lerp。我有 lerp 工作,问题是,它从当前图 block 跳到第一个图 block ,然后过渡到它应该在的第二个图 block 。我使用协程而不是更新函数来完成这项工作(因为更新会导致它只是 lerp 到最终目的地,而不是从当前到第一个,再到第二个)。所以我遇到的是遍历 pawn 的每一步的循环,而不是等待协程完成后再继续它自己的循环。这是代码

public void MoveNextTile()
{
    float remainingMoves = moveSpeed;
    while (remainingMoves > 0)
    {

        if (currentPath == null)
            return;
        //Get the cost from current tile to next tile
        remainingMoves -= map.CostToEnterTile(currentPath[0].x, currentPath[0].y, currentPath[1].x, currentPath[1].y);

        //Move us to the next tile in the sequence
        toVector = map.TileCoordToWorldCoord(currentPath[1].x, currentPath[1].y);
        Vector3 fromVec = transform.position;
        StartCoroutine(MoveObject(fromVec, toVector, 1.0f));


        //transform.position = map.TileCoordToWorldCoord(currentPath[1].x, currentPath[1].y);

        //Remove the old current tile

        this.tileX = currentPath[0].x;
        this.tileY = currentPath[0].y;
        currentPath.RemoveAt(0);
        if (currentPath.Count == 1)
        {
            this.tileX = currentPath[0].x;
            this.tileY = currentPath[0].y;
            currentPath = null;
        }


    }

}
IEnumerator MoveObject(Vector3 source, Vector3 target, float overTime)
{
    float startTime = Time.time;
    while (Time.time < startTime + overTime)
    {
        transform.position = Vector3.Lerp(source, target, (Time.time - startTime) / overTime);
        yield return null;
    }
    transform.position = target;

}

我知道这是一个菜鸟问题。我以前从来不需要在 C# 中执行此操作。预先感谢所有帮助

最佳答案

我建议您研究协程的工作原理。

您的协程没有完全执行然后返回以完成您的 MoveNextTile 函数的其余部分。它实际上一直执行到第一个 yield 语句,然后继续执行 MoveNextTile。每个后续帧将继续运行协程的一个“步骤”,直到下一个 yield 语句以尝试复制异步方法。

你想要做的是告诉你的程序明确地等待你的协程完成。这样做;

yield return StartCoroutine(MoveObject(fromVec, toVector, 1.0f));

当然,您只能在 IEnumerator 内部使用此语句。因此,您必须将 void MoveNextTile 函数更改为 IEnumerator MoveNextTile。你最终得到如下结果;

public IEnumerator MoveNextTile() {

    // Ommited
    while (remainingMoves > 0) {
        //Ommited
        yield return StartCoroutine(MoveObject(fromVec, toVector, 1.0f));
        // Now MoveNextTile will continue after your MoveObject coroutine finishes.
    }
}

关于c# - 让循环等待 Action 完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29703557/

相关文章:

c# - 32 位 .NET 最大字节数组大小是否小于 2GB?

c# - 运算符 '??' 不能应用于类型 'System.DateTime' 的操作数

c - scanf() 方法在 while 循环中不起作用?

c# - 在 Samsung Gear VR 中检测点击

c# - 无法将 'microsoft.Office.Interop.Excel.ApplicationClass' 类型的 COM 对象转换为 'microsoft.Office.Interop.Excel.Application'”

c# - 如何获取 RichTextBox 控件中的当前行?

C - 生成 X 字符词的所有可能性

VBA excel从工作表复制公式并粘贴到多个工作表

android - 使用 Unity3d 访问 Android Activity 状态

c# - C# 中不断增长的对象集合的最佳结构?