对于给定的 帧率运行游戏时连续帧显示的频率。 更多信息
参见 术语表 (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.time
只会增加 0.333,Time.deltaTime
等于 0.333,尽管现实世界中已经过去了 1 秒。
这些属性的未缩放版本(Time.unscaledTime 和 Time.unscaledDeltaTime)会忽略这些限制,并在两种情况下都报告实际经过的时间。这对于任何即使游戏以慢动作播放也应该以固定速度响应的东西都很有用。例如,UI(用户界面) 允许用户与您的应用程序进行交互。Unity 目前支持三种 UI 系统。 更多信息
参见 术语表 交互动画。
下表显示了 16 帧一个接一个地经过的示例,其中一个大的延迟发生在中间的一帧。这些数据说明了各种 Time
类属性如何报告和响应这种大的帧率变化。
帧 | unscaledTime | time | unscaledDeltaTime | 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 (a) | 1.123 (b) | 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.time
和 Time.unscaledTime
同时稳定地增加,表明 Time.timeScale
设置为 1。
在第 8 帧 (a),发生了超过一秒钟的大延迟。当有资源竞争时,这种情况可能会发生。例如,一个操作会阻塞主进程,因为它从磁盘加载大量数据。
当帧延迟超过 Time.maximumDeltaTime
时,Unity 会限制 Time.deltaTime
报告的值以及添加到 Time.time
的值。这避免了如果时间步长超过该值可能会发生的不可取的副作用。如果没有限制,其运动受 Time.deltaTime
缩放的对象理论上可以从一帧移动到下一帧无限远。这会导致卡顿效果,例如,角色不受阻碍地穿过墙壁等障碍物。
您可以在编辑器中调整 Time.maximumDeltaTime
,方法是在 Time 窗口中更改 **允许的最大时间步长** 设置,或者在代码中设置 Time.maximumDeltaTime 属性的值。
默认 Time.maximumDeltaTime
值为三分之一秒 (0.3333333)。这意味着在一个由 Time.deltaTime
控制运动的游戏中,对象的运动从一帧到下一帧的距离受限于它在三分之一秒内可以覆盖的距离,无论自上一帧开始实际经过了多少时间。
以图形形式查看上表中的数据有助于可视化这些时间属性如何彼此相关
在第 8 帧,Time.unscaledDeltaTime
(d) 和 Time.deltaTime
(e) 在报告经过了多少时间方面有所不同。尽管第 7 帧和第 8 帧之间经过了整整一秒钟的真实时间,但 Time.deltaTime
仅报告了 0.333 秒。这是因为 Time.deltaTime
被限制为 Time.maximumDeltaTime
的值。
类似地,Time.unscaledTime
(b) 增加了大约整整一秒钟,因为添加了真实的(未限制的)值,而 Time.time
(c) 只增加了较小的限制值。Time.time
不会赶上经过的真实时间,而是表现得好像延迟只持续了 Time.maximumDeltaTime
的时间。
Time.smoothDeltaTime
属性报告最近 Time.deltaTime
值的近似值,所有变化都根据算法进行了平滑。这是一种避免运动或其他基于时间的计算中出现不希望出现的波动的另一种技术。特别是那些低于 Time.maximumDeltaTime
设置的阈值的计算。平滑算法无法预测未来的变化,但它会逐渐调整其报告的值以平滑最近经过的 Time.deltaTime
值的变化,因此报告的平均时间仍然与实际经过的时间大致相等。
maximumDeltaTime
值也会影响 固定更新循环。物理系统使用由 Time.fixedDeltaTime
定义的固定时间间隔来确定在每一步中模拟多少时间。Unity 试图让物理模拟与经过的时间保持同步,有时会在每一帧中执行多次物理更新。
但是,如果物理模拟落后太多,物理系统可能需要大量步骤才能赶上当前时间。这些追赶步骤本身可能会导致额外的减速。为了避免减速的反馈循环,Time.maximumDeltaTime
值也充当了物理系统在任何两个给定帧之间模拟时间的限制。
如果帧更新处理时间超过 Time.maximumDeltaTime
,物理引擎模拟物理系统各个方面的系统,以便物体可以正确加速并受到碰撞、重力和其它力的影响。 更多信息
参见 术语表 不会尝试模拟任何额外的时间,而是让帧处理赶上。一旦帧更新完成,物理系统就会恢复,好像自它停止以来没有经过时间一样。
结果是,物理对象不会像通常那样以真实时间完美地移动,而是会略微变慢。但是,物理系统仍然跟踪它们,好像它们正在正常移动一样。物理时间的减速通常不会引起注意,并且通常是在游戏性能方面可以接受的折衷方案。
以下流程图说明了 Unity 在单个帧中用于计算时间的逻辑,以及 time、deltaTime、fixedDeltaTime 和 maximumDeltaTime 属性之间的关系。