TL,DR:使用Time.deltaTime作为协程中产量的等待时间是否安全?
为了避免在Short()中使用不必要的逻辑来实现短暂的功能,我将运行一个协程。例如,在我的游戏中,我有一个缓慢的协程,定期检查NPC和播放器之间的距离,如果该距离低于某个阈值,我将运行更频繁的协程,使用光线投射等更昂贵的视线测试。这似乎比在Update()中不断检查所有内容更有效。
我的问题是:使用Time.deltaTime作为yield的等待时间是否安全,从而在协同程序的持续时间内模拟Update()?即yield return new WaitForSeconds(Time.deltaTime);
由于deltaTime不是常数,如果下一帧花费的时间长于最后一帧 - 协同程序是否会延迟到下一帧,或者是整个帧被延迟直到协程结束时发生的可怕事情?我很想让安全缓冲器,例如yield return new WaitForSeconds(Time.deltaTime * 1.2f);
但理想情况下我希望它能够精确地执行每一帧。
答案 0 :(得分:6)
使用Time.deltaTime作为a中产量的等待时间是否安全 协程?
否即可。这不是如何使用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
,除了另外while
变量之外,您通常会在float
循环中使用它,直到您increment
或decrement
达到想要的值。使用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");
}
答案 1 :(得分:1)
如果您想检查每一帧,请WaitForEndOfFrame
如果您不需要特定时间等待
,则没有指向WaitForSeconds您也可以yield return www
等待完成
更新,有CustomYieldInstruction和一些继承用于协同程序,如WaitUntil
答案 2 :(得分:0)
我知道这有点旧,但是今天我只是在寻找有关的东西时碰到了它。
无论如何,程序员的答案是一个好的开始。使用Time.detlaTime并不是释放协程控制的好方法。例如,使用空值将使您进入仿真的下一帧。其次,如果您刚完成的帧有点慢(或者下一帧有点快)会发生什么。请记住,模拟(或游戏)是在帧中运行的,就像电影中的帧一样。因此,使用WaitForSeconds可能会产生一些有趣的效果。例如,如果您请求的时间发生在帧之间,您认为会发生什么?协程将在请求的时间后 恢复控制。因此,如果您希望在协程中的每个循环上都射出一个WaitForSeconds(Time.deltaTime),那么您很有可能会跳过偶尔的帧(有时更多)。
我有一个同事在一个运行时间很长的协程中做了很多WaitForSeconds,经过的总时间比预期的要长5到10秒。在请求的时间内由于帧错误而部分丢失的错误将累加起来,并且与自然界中的错误趋于平均的情况不同,这些错误将始终累加 up 。这是因为经过的时间总是大于或等于请求的时间。
程序员的答案向您展示了如何使用Time.deltaTime获得模拟时间的流逝。我应该警告您,一旦您开始使用null以外的功能来释放对协程的控制,那么Time.deltaTime可能会停止为您工作。
如果您使用null后跟一些代码,然后使用WaitForEndFrame,则当协程恢复控制时,您仍将位于同一帧内。由于您仍处于与调用WaitForEndFrame之前相同的帧,因此经过的模拟时间将为零,但Time.deltaTime将不为零。因此,是的,一旦开始混合使用不同的收益类型,测量时间就会变得棘手。您还应该注意在框架和固定框架之间进行切换。使用WaitForFixedUpdate将使您进入固定帧的时间。在WaitForFixedUdpate之后调用Time.fixedDeltaTime将为您提供该固定帧与上一个固定帧之间的时间,这与Time.deltaTime或帧的任何定时无关。