繁体   English   中英

Unity3D - 使用 Time.deltaTime 作为协程的等待时间

[英]Unity3D - Using Time.deltaTime as wait time for a coroutine

TL,DR:在协程中使用 Time.deltaTime 作为产量的等待时间是否安全?

通常为了避免在 Update() 内部为短期功能使用不必要的逻辑,我将运行一个协程。 例如,在我的游戏中,我有一个缓慢的协程,它会定期检查 NPC 和玩家之间的距离,如果该距离低于某个阈值,我将运行更频繁的协程,并使用光线投射等进行更昂贵的视线测试。这似乎比在 Update() 中不断检查所有内容要高效得多。

我的问题是:使用 Time.deltaTime 作为产量的等待时间,从而在协程的持续时间内模拟 Update() 是否安全? ie yield return new WaitForSeconds(Time.deltaTime);

由于 deltaTime 不是恒定的,如果下一帧花费的时间比上一帧长,会发生什么情况 - 协程是否延迟到下一帧,或者整个帧被延迟到协程完成后会发生什么可怕的事情? 为了安全起见,我很想允许一个缓冲区,例如yield return new WaitForSeconds(Time.deltaTime * 1.2f); 但理想情况下,我希望它精确地执行每一帧。

使用 Time.deltaTime 作为协程中产量的等待时间是否安全?

没有 这不是如何使用WaitForSeconds函数。 WaitForSeconds以秒为参数,而不是Time.deltaTime在每一帧中提供的微小值。

下面是如何使用WaitForSeconds函数的示例。

IEnumerator waitFunction1()
{
    Debug.Log("Hello Before Waiting");
    yield return new WaitForSeconds(3); //Will wait for 3 seconds then run the code below
    Debug.Log("Hello After waiting for 3 seconds");
}

至于等待Time.deltaTime ,除了另一个float变量之外,您通常在while循环中使用它,您将incrementdecrement直到达到所需的值。 使用Time.deltaTime优点是您可以看到等待时间在等待时离开。 您可以将其用于倒计时或计时。 你也把yield return null; while循环中,以便 Unity 也允许其他脚本运行,并且您的应用程序不会冻结。 下面是如何使用Time.deltaTime等待 3 秒的示例。 您可以轻松地将其变成倒数计时器。

IEnumerator waitFunction2()
{
    const float waitTime = 3f;
    float counter = 0f;

    Debug.Log("Hello Before Waiting");
    while (counter < waitTime)
    {
        Debug.Log("Current WaitTime: " + counter);
        counter += Time.deltaTime;
        yield return null; //Don't freeze Unity
    }
    Debug.Log("Hello After waiting for 3 seconds");
}

如果你想检查每一帧有WaitForEndOfFrame

如果您不需要特定的等待时间,则 WaitForSeconds 没有意义

你也可以yield return www等待它完成

更新,有CustomYieldInstruction和一些在协程中使用的继承,比如 WaitUntil

我知道这有点旧,但我今天在寻找相关的东西时偶然发现了它。

无论如何,程序员的回答是一个好的开始。 使用 Time.detlaTime 不是释放协程控制的好方法。 首先,使用空值将使您进入模拟中的下一帧。 其次,如果您刚刚完成的帧有点慢(或下一帧有点快)会发生什么。 请记住,模拟(或游戏)以帧为单位运行,就像电影中的帧一样。 因此,使用 WaitForSeconds 可以产生一些有趣的效果。 例如,如果您请求的时间发生在帧之间,您认为会发生什么? 协程将在请求的时间重新获得控制权。 因此,如果您希望在协程中的每个循环中只触发 WaitForSeconds(Time.deltaTime),那么您很可能会跳过偶尔的帧(有时更多)。

我有一个同事在一个长时间运行的协程中做了一堆 WaitForSeconds,所经过的总时间比预期的要长 5 到 10 秒。 通过在要求的时间框架错误的一部分那些关加起来,不像性质,其中的错误往往会平均出来,这些错误将永远积少成多 这是因为经过的时间量总是大于或等于请求的时间量。

Programmer's answer向您展示了如何使用 Time.deltaTime 来获取模拟时间的流逝。 我应该警告你,一旦你开始使用 null 以外的东西来释放对协程的控制,那么 Time.deltaTime 可能会停止为你工作。

如果您使用空后跟一些代码后跟一个 WaitForEndFrame,则当协程恢复控制时,您仍将处于同一帧内。 因为您仍然在调用 WaitForEndFrame 之前的同一帧中,所以经过的模拟时间将为零,但 Time.deltaTime 不会为零。 所以,是的,一旦你开始混合不同的返回类型,测量时间就会变得棘手。 您还应该小心在帧和固定帧之间切换。 使用 WaitForFixedUpdate 将使您进入固定帧的时间。 在 WaitForFixedUdpate 之后调用 Time.fixedDeltaTime 将为您提供该固定帧和前一个固定帧之间的时间,这与 Time.deltaTime 或帧的任何计时无关。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM