【问题标题】:while conditional inside coroutine does not loop, hangs而协程内部的条件不循环,挂起
【发布时间】:2019-08-06 20:40:09
【问题描述】:

我有一个想要包含 2 秒暂停的协程。我使用了一个 while 循环来检查 initialTimenow 之间的差异来检查它已经持续了多长时间:

IEnumerator MyCoroutine(){
    Debug.Log("Before the counter");

    //`Time.time` returns the number of seconds since app launch (i.e., `72.33448`)
    float initialTime = Time.time;
    Debug.Log("initialTime = " + initialTime);
    float now = initialTime;

    while(now - initialTime < 2.0f){
        yield return null;
        now = Time.time;
        Debug.Log("now = " + now);
    }

    Debug.Log("After the counter");

    //...Stuff that happens after delay
}

由于某种原因,我运行它大约 1/5 次,它不会完全在循环中,而是无法执行整个协程:在控制台中我看到 Debug.Log("now = " + now);只执行一次,Debug.Log("After the counter"); 永远不会发生——我希望适当的 while 循环挂起可以无限打印Debug.Log("now = " + now);

这个定时器的逻辑有什么问题会导致这种行为?

编辑:如果可能的话,我更愿意遵守 Unity 使用 StartCoroutine()StopCoroutine() 而不是 System.Threading 的规范。

【问题讨论】:

  • 为什么返回IEnumerator 而不是IEnumerable?我不是 Unity 的人,所以我不知道这是否是 Unity 的事情。
  • 因为我不知道 IEnumerable 是一件事 :P ... 现在调查一下。
  • 正如 Vikhram 所说,似乎根本没有理由使用 IEnumeratorIEnumerable - 你没有返回任何有意义的数据。 Thread.Sleep 可以很好地暂停你的线程。
  • @gunr2171 我仍在努力理解其中的区别,但要明确一点:我将MyCoroutine() 视为一种只需要同时执行操作的void 方法,但需要2 秒后延迟。我编辑了上面的代码以反映IEnumerator中会发生更多的事情(这不仅仅是无缘无故的)
  • @Vikhram 在此处提出解决方案之前,您应该先了解协程的工作原理。让线程休眠将是一个完全不可接受的解决方案。它会冻结整个应用程序两秒钟。

标签: c# unity3d while-loop


【解决方案1】:

解决方案相当简单。

首先,您需要一个像以前那样的 IEnumerator,而不是 cmets 中建议的 IEnumerable。非常不同的东西。

其次,Unity 有一个内置函数,可以在您指定的时间内暂停您的协程。使用WaitForSeconds(2f)(2 是秒数)或WaitForSecondsRealtime(2f)

WaitForSeconds“等待”2 秒,同时考虑帧率。

WaitForSecondsRealTIme“等待”2 秒,不考虑帧率。

IEnumerator MyCoroutine(){
    Debug.Log("Before the counter");

    yield return new WaitForSeconds(2f); 

    Debug.Log("After the counter");

    //...Stuff that happens after delay
}

【讨论】:

  • 非常感谢!由于上面的 cmets 提供了一些关于返回 null 以外的东西的线索,我正在发现 WaitForSeconds() 的过程中,意识到我设计过度了。
  • 我没有测试过,但我认为WaitForSeconds和WaitForSecondsRealTime之间的区别与帧率无关。非实时变量更有可能基于 Unity 引擎的 timeScale(即引擎计时的速度,例如物理模拟)。
  • WaitForSecondsRealTime 使用未缩放时间而不是缩放时间。未缩放的时间与帧速率无关
  • @Immorality WaitForSeconds 也应该与帧率无关。应该像 Nikaas 所说的那样根据 timeScale 变化,而不是根据 freamerate。
猜你喜欢
  • 1970-01-01
  • 2019-08-28
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-26
  • 1970-01-01
相关资源
最近更新 更多