'How do I know if a Coroutine is still "waiting"? [closed]

All I can find online is "How to check if a coroutine is running", which is not what I want.

Say if I have a coroutine with

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

Is there a way to know if this statement is still "pending"?

Because if I use the Boolean trick such as

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

The isRunning flag will "always" be true if I stop the coroutine before SomeBool is set to true.

I have tested that this is indeed the case! Anything after the yield statement will never be run!

And since it's never ran, any checking is useless, whether it's isRunning or SomeBool.

So it failed the function of "Checking if the coroutine is still running"!

Is there a way to "do the right job"?

So if I finally set SomeBool to true from another part of the code, I know that there is still a WaitUntil waiting for it? If not, then somehow restart the coroutine so it won't "stuck forever and crash the game"!?

Much appreciated!



Solution 1:[1]

Use CustomYieldInstruction.keepWaiting. Make the object you yield return available outside the coroutine and things can check if the coroutine would wait if it were to be checked right now:

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 waitTest;

        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;
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1