【问题标题】:Stopping all code execution until condition is met (Unity C#)停止所有代码执行直到满足条件(Unity C#)
【发布时间】:2020-11-04 12:57:22
【问题描述】:

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

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

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

【问题讨论】:

  • 将您所在的方法转换为协程(返回值为IEnumerator),然后使用StartCoroutine 调用它,然后在此处显示的代码中,调用WaitUntilButtonPress() 而不使用@ 987654326@
  • 如果@derHugo 的回答有帮助,请考虑accepting it

标签: c# unity3d


【解决方案1】:

Coroutine 确实不会延迟通过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();
}

或者您可以使用回调模式并在等待完成后执行回调。因为我不知道你的 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();
}

或者相同但没有 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();
}

【讨论】:

  • 很好,希望对您有所帮助。
  • 也许协程所在的代码块中的所有代码都应该是更好的措辞。我把重点放在了所有方面,因为我发现了很多停止协程的资源,但尽管我尽了最大努力,但没有任何其他资源
猜你喜欢
  • 2016-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多