首页 > 解决方案 > 我如何知道协程是否仍在“等待”?

问题描述

我在网上只能找到“如何检查协程是否正在运行”,这不是我想要的。

说如果我有一个协程

yield return new WaitUntil(()=> SomeBool);

有没有办法知道这个声明是否仍然“待定”?

因为如果我使用布尔技巧,例如

isRunning = true;
yield return new WaitUntil(()=>SomeBool);
isRunning = false;

如果isRunningtrueSomeBool设置为true.

我测试过确实是这样!语句之后的任何内容yield都不会运行!

而且由于它从未运行过,因此任何检查都是无用的,无论是isRunning还是SomeBool.

所以“检查协程是否还在运行”的功能失败了!

有没有办法“做正确的工作”?

那么如果我最后从另一部分代码设置SomeBooltrue,我知道还有一段WaitUntil等待吗?如果不是,那么以某种方式重新启动协程,这样它就不会“永远卡住并导致游戏崩溃”!?

非常感激!

标签: c#unity3dcoroutine

解决方案


使用CustomYieldInstruction.keepWaiting. 使您的对象yield return在协程之外可用,并且可以检查协程是否会等待,如果它现在被检查:

public class TestScript : MonoBehaviour
{
    CustomYieldInstruction waitTest;
    Coroutine waitingCoroutine;
    bool waitBool;

    void Start()
    {
        waitBool = false;
        waitingCoroutine = StartCoroutine(WaitingCoroutine());
        StartCoroutine(TriggeringCoroutine());
    }

    private IEnumerator WaitingCoroutine()
    {
        waitTest = null;
        yield return null;

        waitTest = new WaitUntil(() => waitBool);
        yield return waitTest;

        waitTest = new WaitUntil(() => waitBool);
        yield return waitTest;

        waitingCoroutine = null;
    }
 
    private IEnumerator TriggeringCoroutine()
    {
        Debug.Log(string.Format("First frame waiting: {0}", IsWaiting())); // false
        yield return null;

        Debug.Log(string.Format("Second frame waiting: {0}", IsWaiting())); // true
        yield return null;

        waitBool = true;
        Debug.Log(string.Format("Third frame waiting: {0}", IsWaiting())); // false
        yield return null;

        Debug.Log(string.Format("Fourth frame waiting: {0}", IsWaiting())); // false
        yield return null;

        Debug.Log(string.Format("Fifth frame waiting: {0}", IsWaiting())); // false

    }

    private bool IsWaiting()
    {
        return waitingCoroutine != null && waitTest != null && waitTest.keepWaiting;
    }
}

推荐阅读