停止所有代码执行,直到满足条件(Unity C#)

And*_* M. 0 c# unity-game-engine

我发现了很多关于协程试图解决这个问题的信息(waitUntil()、while 循环、不同的 yield 变体等)但我对它们的问题要么是代码的其余部分仍然被执行,要么协程中的代码尚未完成,或者它无限循环并冻结 Unity 编辑器。例如,即使没有按下任何按钮,以下代码也会打印调试消息(在协程仍在等待按钮按下以完成其代码块本身的同时)。

ChoiceButtons.enableButtons();
StartCoroutine(WaitUntilButtonPress());
UnityEngine.Debug.Log("It skipped it.");
ChoiceButtons.setButtonPressed(false);
ChoiceButtons.disableButtons();

Run Code Online (Sandbox Code Playgroud)

我需要能够停止所有进一步的代码执行,直到特定函数返回 true。是否有我刚刚错过的特定功能可以完成此操作或我必须设置循环的特定方式(可能使用诸如 SpinWait.SpinUntil() 之类的线程函数之类的古怪东西?)。老实说,我完全不知所措,因为它似乎在协程中肯定会有自己的功能,但我找不到任何东西

der*_*ugo 5

一个协程没有耽误这是通过调用它的方法StartCoroutine本身!否则你的主线程会冻结,从而消除协程的全部目的;)

您绝对不想做的是因为您冻结它“停止所有代码执行”,因为……这也会冻结您的主线程->您将无法按下任何按钮;)


如果您想等待例程完成,您有两个主要选择:

要么使整个调用方法成为例程

public void YourOriginalMethod()
{
    StartCoroutine (YourMethodRoutine());
}

private IEnumerator YourMethodRoutine ()
{
    ChoiceButtons.enableButtons();
    // This executed the wait routine and wait for it to finish
    yield return WaitUntilButtonPress();

    ChoiceButtons.setButtonPressed(false);
    ChoiceButtons.disableButtons();
}
Run Code Online (Sandbox Code Playgroud)

或者您可以使用回调模式并在等待完成后执行回调。因为我不知道你WaitForButtonPress在这里是虚拟代码

public void YourOriginalMethod()
{
    ChoiceButtons.enableButtons();

    // Start the routine and pass a callback what to do when done
    // here e.g. as lambda expression
    StartCoroutine (WaitUntilButtonPress(() =>
    {
        ChoiceButtons.setButtonPressed(false);
        ChoiceButtons.disableButtons();
    }));
}

private IEnumerator WaitUntilButtonPress (Action whenDone)
{
    // Whatever your routine is waiting for
    yield return new WaitUntil(()=>buttonPressed);

    whenDone?.Invoke();
}
Run Code Online (Sandbox Code Playgroud)

或者相同但没有 lambda 而是一个方法

public void YourOriginalMethod()
{
    ChoiceButtons.enableButtons();

    // Start the routine and pass a callback what to do when done
    StartCoroutine (WaitUntilButtonPress(AfterButtonWasPressed));
}

private void AfterButtonWasPressed()
{
    ChoiceButtons.setButtonPressed(false);
    ChoiceButtons.disableButtons();
}

private IEnumerator WaitUntilButtonPress (Action whenDone)
{
    // Whatever your routine is waiting for
    yield return new WaitUntil(()=>buttonPressed);

    whenDone?.Invoke();
}
Run Code Online (Sandbox Code Playgroud)