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

本文关键字:程序 等待时间 使用 Time deltaTime Unity3D- | 更新日期: 2023-09-27 17:57:58

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

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

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

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

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

使用Time.deltaTime作为协同出游?

。这不是使用WaitForSeconds函数的方法。CCD_ 4以秒为单位作为参数,而不是CCD_。

以下是如何使用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等待,您通常在while循环中使用它,此外还有另一个float变量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秒。在请求的时间内,由于帧错误的一部分而偏离的错误将相加,与错误趋于平均的性质不同,这些错误总是将相加。这是因为经过的时间总是大于或等于请求的时间。

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

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