【问题标题】:Unity Coroutine Not WaitingUnity协程不等待
【发布时间】:2020-11-02 16:32:52
【问题描述】:

我正在制作一款游戏,我希望叠加层在消失之前出现指定的秒数。我正在使用协程来执行此操作,但它现在正在工作。有没有办法解决这个问题,或者我应该用另一种方式来解决。我没有收到任何错误,但 coverObject 不显示 3 秒并隐藏 2 秒,如代码中指定的那样。

代码:

void playRound()
{
    coverObject.gameObject.SetActive(true);
    for (int i = 0; i < keys - 1; i++)
    {
        GameObject instantiated = Instantiate(key);
    }
    waitSecs(3);
    coverObject.gameObject.SetActive(true);

    GameObject instantiatedCorrect = Instantiate(key);
    correctKey = instantiatedCorrect;

    waitSecs(2);
    coverObject.gameObject.SetActive(false);
}
    
void waitSecs(int seconds)
{
    StartCoroutine(WaitSecsCoroutine(seconds));
}

IEnumerator WaitSecsCoroutine(int seconds) 
{
    yield return new WaitForSeconds(seconds);
}

【问题讨论】:

  • 请解释“不工作”,您是否遇到任何错误? 究竟是什么不起作用?

标签: unity3d game-engine coroutine


【解决方案1】:

您的协程确实在等待...... 但是:协程不会延迟启动它的方法中的任何内容。它只会延迟协程中的代码!

因此,按照您的方式,它只会执行playRound 中的其余代码,无需等待。

您更愿意做的是在协程中运行整个事情,例如

void playRound()
{
    StartCoroutine(PlayRoundRoutine());
}

IEnumerator PlayRoundRoutine() 
{
    coverObject.gameObject.SetActive(true);
    for (int i = 0; i < keys - 1; i++)
    {
        GameObject instantiated = Instantiate(key);
    }

    yield return new WaitForSeconds(3f);

    coverObject.gameObject.SetActive(true);

    GameObject instantiatedCorrect = Instantiate(key);
    correctKey = instantiatedCorrect;

    yield return new WaitForSeconds(2f);

    coverObject.gameObject.SetActive(false);
}

【讨论】:

    【解决方案2】:

    您的方法playRound 将在WaitSecsCoroutine 协程产生时继续运行。这是因为一旦到达yield return 语句,控制就会返回给调用方法。

    以下情况正在发生:

    • playRound 被调用
    • 您的游戏对象被实例化
    • waitSecs 被调用
    • waitSecs 调用协程 waitSecsCoroutine
    • waitSecsCoroutine 到达yield return new WaitForSeconds()
    • 控制权现在返回给waitSecs,然后又返回给PlayRound
    • playRound 继续 coverObject.gameObject.SetActive(true); 和后续代码,而 waitSecsCoroutine 仍在等待。

    您需要做的是将playRound 也设为协程,并使用yield return WaitSecsCoroutine 使函数停止执行,直到WaitSecsCoroutine 完成:

    IEnumerator playRound()
    {
        coverObject.gameObject.SetActive(true);
        for (int i = 0; i < keys - 1; i++)
        {
            GameObject instantiated = Instantiate(key);
        }
        yield return WaitSecsCoroutine(3);//This now waits until WaitSecsCoroutine is finished
        coverObject.gameObject.SetActive(true);
        GameObject instantiatedCorrect = Instantiate(key);
        correctKey = instantiatedCorrect;
        yield return WaitSecsCoroutine(2);
        coverObject.gameObject.SetActive(false);
    }
    

    但是请注意,您也可以直接从您的 playRoudn 方法调用 WaitForSeconds,一旦它是协程,不需要单独的函数

    IEnumerator playRound()
    {
        coverObject.gameObject.SetActive(true);
        for (int i = 0; i < keys - 1; i++)
        {
            GameObject instantiated = Instantiate(key);
        }
        yield return new WaitForSeconds(3);
        coverObject.gameObject.SetActive(true);
        GameObject instantiatedCorrect = Instantiate(key);
        correctKey = instantiatedCorrect;
        yield return new WaitForSeconds(2);
        coverObject.gameObject.SetActive(false);
    }
    

    或者,您可以将等待后要执行的代码移动到您的 WaitSecsCoroutine 方法中。

    【讨论】:

      猜你喜欢
      • 2017-02-24
      • 1970-01-01
      • 2018-07-26
      • 1970-01-01
      • 1970-01-01
      • 2018-10-26
      • 1970-01-01
      • 1970-01-01
      • 2017-11-05
      相关资源
      最近更新 更多