Version: 6000.3
语言: 中文
修复更新
游戏内时间和实时

处理时间变化

对于给定的帧速率秒帧数正在运行的游戏中显示连续帧的频率。更多信息
请参阅术语表
(FPS),则各个帧的持续时间往往会有所不同。这些变化可能很小。例如,在以 60 的速度运行的游戏中FPS查看第一人称射击游戏,每秒帧数。
请参阅术语表
,每秒实际帧数可能略有不同,因此每帧持续 0.016 到 0.018 秒之间。当应用程序执行大量计算或垃圾回收时,或者当来自其他应用程序的资源存在竞争时,可能会出现更大的变化。

记录经过的时间

Time.time 表示自应用程序启动以来经过的时间量,因此通常会持续稳定地上升。Time.deltaTime 表示自上一帧以来经过的时间量,因此理想情况下保持相当恒定。这两个值都基于游戏内而不是实时,这意味着它们会考虑你应用的任何时间缩放。例如,如果将慢动作效果的 Time.timeScale 设置为 0.1,则Time.time以实时的 10% 的速率增加。实时 10 秒后,值Time.time将增加 1。

除了减慢或加快游戏时间外,您还可以将Time.timeScale设置为零以暂停游戏。在这种情况下,Unity 仍会调用Update方法,但Time.time根本没有增加,并且Time.deltaTime为零。

限制记录的时间变化

这些值也由 Time.maximumDeltaTime 的值限制。这些属性报告的任何暂停或帧速率变化的长度永远不会超过Time.maximumDeltaTime.例如,如果发生一秒的延迟,但maximumDeltaTime设置为默认值 0.333,Time.timewonly 增加 0.333 且Time.deltaTime等于 0.333,尽管在现实世界中已经过去了一秒。

其中每个属性的未缩放版本(Time.unscaledTimeTime.unscaledDeltaTime)忽略了这些限制,并报告了这两种情况下实际运行的时间。这对于任何应该以固定速度响应的东西都很有用,即使游戏以慢动作进行也是如此。这方面的一个例子是 UI 交互动画。

下表显示了 16 帧相继经过的示例,其中一个大延迟在单个帧上发生。这些数字说明了各种Time类属性报告并响应帧速率的这种巨大变化。

框架 未缩放时间 时间 未缩放的 DeltaTime deltaTime smoothDeltaTime (平滑增量时间)
1 0.000 0.000 0.018 0.018 0.018
2 0.018 0.018 0.018 0.018 0.018
3 0.036 0.036 0.018 0.018 0.018
4 0.054 0.054 0.018 0.018 0.018
5 0.071 0.071 0.017 0.017 0.018
6 0.089 0.089 0.018 0.018 0.018
7 0.107 0.107 0.018 0.018 0.018
8 (一个) 1.123 () 0.440 (c) 1.016 (d) 0.333 (e) 0.081 (f)
9 1.140 0.457 0.017 0.017 0.066
10 1.157 0.474 0.017 0.017 0.056
11 1.175 0.492 0.018 0.018 0.049
12 1.193 0.510 0.018 0.018 0.042
13 1.211 0.528 0.018 0.018 0.038
14 1.229 0.546 0.018 0.018 0.034
15 1.247 0.564 0.018 0.018 0.031
16 1.265 0.582 0.018 0.018 0.028

帧 1 到 7 以每秒约 60 帧的稳定速率运行。你可以看到两者Time.timeTime.unscaledTime一起稳步增长,表明Time.timeScale设置为 1。

在第 8 (a) 帧上,出现了略高于一秒的大延迟。当存在资源竞争时,就会发生这种情况。例如,一个作在从磁盘加载大量数据时阻止了主进程。

当帧延迟超过Time.maximumDeltaTime,Unity 将报告的值限制为Time.deltaTime以及添加到Time.time.这避免了在时间步长超过该量时可能发生的不良副作用。如果没有限制,则其移动缩放为Time.deltaTime理论上可以从一帧移动无限距离到下一帧。这可能会导致故障效果,例如,角色可以畅通无阻地穿过墙壁等障碍物。

您可以调整Time.maximumDeltaTime在编辑器中,通过更改时间窗口中的允许的最大时间步长设置,或在代码中设置 Time.maximumDeltaTime 属性的值。

默认值Time.maximumDeltaTime值为三分之一秒 (0.3333333)。这意味着在运动由Time.deltaTime,对象从一帧到下一帧的移动仅限于它在三分之一秒内可以覆盖的距离,无论自上一帧以来实际经过了多少时间。

以图表形式查看上表中的数据有助于可视化这些时间属性之间的行为方式:

对于延迟帧 8,增量时间报告其默认最大值 0.333 秒,而未缩放的增量时间报告自上一帧以来经过的实时时间,即 1.016 秒。
对于延迟帧 8,增量时间报告其默认最大值 0.333 秒,而未缩放的增量时间报告自上一帧以来经过的实时时间,即 1.016 秒。

在第 8 帧上,Time.unscaledDeltaTime (d) 和Time.deltaTime (e) 他们报告的经过的时间不同。尽管在第 7 帧和第 8 帧之间经过了整整一秒的实时时间,Time.deltaTime仅报告 0.333 秒。这是因为Time.deltaTime上限为Time.maximumDeltaTime价值。

在延迟帧 8 之前,时间和未缩放时间相等,并且以相同的速率增加。延迟帧导致两个值因帧 8 的增量时间与未缩放增量时间之间的差值而发散。
在延迟帧 8 之前,时间和未缩放时间相等,并且以相同的速率增加。延迟帧导致两个值因帧 8 的增量时间与未缩放增量时间之间的差值而发散。

同样地Time.unscaledTime (b) 增加了大约一整秒,因为添加了真实(无上限)值,而Time.time (c) 仅增加了较小的上限值。Time.time赶不上经过的实时时间,而是表现得好像延迟只是Time.maximumDeltaTime在持续时间上。

增量时间值在延迟帧 8 上显着峰值,但在其他帧中保持一致。相反,平滑的增量时间在第 8 帧上略有上升,但将增加分散到后续帧中。在接下来的 8 帧中,它仍然高于 delta 时间,同时逐渐呈下降趋势。
增量时间值在延迟帧 8 上显着峰值,但在其他帧中保持一致。相反,平滑的增量时间在第 8 帧上略有上升,但将增加分散到后续帧中。在接下来的 8 帧中,它仍然高于 delta 时间,同时逐渐呈下降趋势。

Time.smoothDeltaTime属性报告最近的近似值Time.deltaTime根据算法平滑所有变化的值。这是避免运动或其他基于时间的计算中出现不良波动的另一种技术。特别是那些低于Time.maximumDeltaTime.平滑算法无法预测未来的变化,但它会逐渐调整其报告的值,以平滑最近经过的变化Time.deltaTime值,以便平均报告时间与实际经过的时间大致相等。

时间变化和固定更新循环

maximumDeltaTime值也会影响固定更新循环。物理系统使用由Time.fixedDeltaTime以确定每个步骤中要模拟的时间。Unity 会尝试使物理模拟与经过的时间保持同步,有时每帧执行多个物理更新。

但是,如果物理模拟落后太多,物理系统可能需要大量的步骤才能赶上当前时间。这些追赶步骤本身可能会导致额外的减速。为了避免减速的反馈循环,将Time.maximumDeltaTime值还充当物理系统在任何两个给定帧之间模拟的时间量的限制。

如果帧更新时间长于Time.maximumDeltaTime处理,物理引擎模拟物理系统各个方面的系统,使物体能够正确加速并受到碰撞、重力和其他力的影响。更多信息
请参阅术语表
不尝试模拟任何额外的时间,而是让帧处理赶上。帧更新完成后,物理会恢复,就好像它停止后没有经过任何时间一样。

这样做的结果是物理对象不会像往常那样实时完美移动,而是会稍微减慢速度。然而,物理系统仍然会跟踪它们,就好像它们正常移动一样。物理时间的减慢通常并不明显,并且通常是与游戏性能的可接受的权衡。

Unity 的时间逻辑

以程图说明了 Unity 用于计算单个帧中时间的逻辑,以及 timedeltaTimefixedDeltaTimemaximumDeltaTime 属性之间的关系。

Unity 计算增量时间,如有必要,将其减少到最大增量时间,并将此值添加到总经过时间中。如果总经过时间现在至少比固定时间值提前一个固定时间步长,则 Unity 将执行固定更新。如果没有,它会执行定期帧更新。
Unity 计算增量时间,如有必要,将其减少到最大增量时间,并将此值添加到总经过时间中。如果总经过时间现在至少比固定时间值提前一个固定时间步长,则 Unity 将执行固定更新。如果没有,它会执行定期帧更新。

其他资源

修复更新
游戏内时间和实时