Unity协程不等待

Unity Coroutine Not Waiting

我正在制作一款游戏,我希望叠加层在消失前显示指定的秒数。我正在使用协程来执行此操作,但它现在正在运行。有没有办法解决这个问题,或者我应该用另一种方式来解决。我没有收到任何错误,但 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);
}

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

因此,按照您的方式,它将直接执行 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);
}

你的方法 playRound 将保持 运行 而 WaitSecsCoroutine 协程正在屈服。这是因为一旦到达 yield return 语句,控制权就会返回到调用方法。

发生以下情况:

  • playRound被称为
  • 你的游戏对象被实例化
  • waitSecs被称为
  • waitSecs 调用协程 waitSecsCoroutine
  • waitSecsCoroutine 达到 yield return new WaitForSeconds()
  • 控制权现在返回给 waitSecs,后者又 returns 到 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 方法中。