c# - 使用协程循环

标签 c# unity-game-engine coroutine

我对循环情况下的协程行为有疑问,请参阅以下代码摘录作为在 Unity C# 脚本上完成的示例:

void Start() {
    StartCoroutine(FSM());
}

IEnumerator FSM() {
    state="State1";
    while (true) {
        Debug.Log("State "+state);
        yield return StartCoroutine(state);
    }
}

IEnumerator State1() {
    while (true) {
        if (stateTransitionCond) {
            state = "NextState";
            yield break;
        }
        yield return null; 
    }
}

状态机工作正常,但是当当前状态为 Status1 (stateTransitionCond==false) 时,由于 循环内的 yield return null State1() 例程,我期望 FMS() 内的循环也会执行另一次迭代,生成调试日志“Debug.Log("State "+state);”。

换句话说,我期待大量的调试日志(当状态为 Status1 时,State1() 例程的每次迭代都有一个),但实际上,当状态为 Status1 时,只执行了 1 次。

所以我想我错过了一些关于 yield 功能的事情,有没有人可以解释我这种行为?

最佳答案

您的问题源于这样一个事实:您的代码在 stateTransitionCond == true 之前不会突破 State1() 方法。

启动协程的方法 FSM()State1 完成之前不会返回。换句话说,在协程完成之前,控制流不会返回到调用方法。我相信这是因为您在 FSMyield-ing State1 (产生另一个协程)。显然,“正常”方法不会等待协程完成才继续执行。

请参阅下面的代码示例以获取说明性示例:

using UnityEngine;
using System.Collections;

public class CoroutineTest : MonoBehaviour {
    // current FSM state
    public string state = ""; 

    void Start()
    {   
        StartCoroutine(FSM());
    }   

    IEnumerator FSM()
    {   
        state = "State1";

        while (true)
        {   
            Debug.Log("State: " + state);
            // ExecuteOnce will execute exactly once before returning to the outer function
            yield return StartCoroutine(ExecuteOnce());

            // ExecuteIndefinitely will execute indefinitely until its while() loop is broken
            // uncomment to test
            //yield return StartCoroutine(ExecuteIndefinitely());
        }   
    }   

    IEnumerator ExecuteOnce()
    {   
        Debug.Log("Calling ExecuteOnce()");
        yield return new WaitForSeconds(1f);
    }   

    IEnumerator ExecuteIndefinitely()
    {   
        Debug.Log("Calling ExecuteIndefinitely()");
        while (true)
        {   
            Debug.Log("Inside ExecuteIndefinitely()");
            yield return new WaitForSeconds(1f);
        }   
    }   
}

关于c# - 使用协程循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19220852/

相关文章:

c# - 如果从 using 语句中抛出异常,是否仍会调用清理逻辑?

c# - 使用 updatepanel 初始工作正常,但一段时间后不起作用

c# - 如何编写测试以公开从 using block 返回任务?

ios - 如何修复 clang 错误 : symbol(s) not found for architecture arm64

c# - 团结 : Omnisharp is not finding referenced projects in VSCode

python - PyQt5 和 Asyncio

c# - 如何将字符串转换为 Int 集合

android - 取消 Google Play 游戏登录后 Facebook 登录崩溃(反之亦然)

coroutine - 协程vs纤维差异澄清

c# - Mono Tasklet/协程的开销