对于Time类,有一张比较重要的图,以及Unity的官方文档链接Time类
中文图片来自详解Unity中Time类的用法与深入探究
1. Time.deltaTime
其真实意思是游戏世界内的帧与帧之间的时间间隔,而不是真实世界内的帧与帧之间的时间间隔,原因在于,它会受到 Time.timeScale的影响,timeScale变大,deltaTime变大,timeScale变小,deltaTime也变小
- 当timeScale = 1
timeScale当前为1,deltaTime大概在0.0015上下浮动
- 当timeScale = 0.5
deltaTime大概在0.00075上下浮动,也就是0.0015 * timeScale = 0.0015 * 0.5 = 0.00075
- 当timeScale = 2
deltaTime大概在0.003上下浮动,也就是0.0015 * timeScale = 0.0015 * 2 = 0.003
其结果侧面说明了,deltaTime并不是真实的帧间隔的时间,因为真实的帧率受到硬件和软件环境的影响,不是依靠timeScale 就可以改变的
2. Time.unscaledDeltaTime
从字面意思上看是不受timeScale 影响的帧与帧之间的时间间隔
- 当timeScale = 1
unscaledDeltaTime此时大概在0.0015上下浮动
- 当timeScale = 0.5
依旧在0.0015上下浮动
- 当timeScale = 2时
整体大概还是在0.0015上下浮动
说明timeScale 的变化对于unscaledDeltaTime是没有影响的
3. Time.deltaTime,Time.unscaledDeltaTime,Time.timeScale之间的关系
从上面的验证可以很容易得出
当 timeScale = 1 时,Time.deltaTime == Time.unscaledDeltaTime = 0.0015
当 timeScale = 0.5 时,Time.deltaTime = Time.unscaledDeltaTime * 0.5 = 0.00075
当 timeScale = 2 时,Time.deltaTime = Time.unscaledDeltaTime * 2 = 0.003
即得出 Time.deltaTime = Time.unscaledDeltaTime * Time.timeScale
4. 和Update方法间的关系
Update方法是Mono的生命周期函数,每一帧都会调用,那么这个每一帧之间的真实时间间隔是多少呢?
我们可以使用Time.realtimeSinceStartup来进行验证,Time.realtimeSinceStartup是游戏开始以来的实际时间,并且不受Time.timeScale影响
- 当timeScale = 1 时
对每2帧的时间做一个差的计算,大概是在0.0015上下浮动
- 当timeScale = 0.5 时
对每2帧的时间做一个差的计算,依旧大概是在0.0015上下浮动
- 当timeScale = 2 时
对每2帧的时间做一个差的计算,依旧大概是在0.0015上下浮动
- 当timeScale = 0 时
可以看到Update依旧在调用,并且帧与帧之间的时间间隔依旧在0.0015上下浮动
从这里可以得出结论了,即Update更新调用的真实时间间隔就是unscaledDeltaTime,而在游戏内的帧的时间间隔是Time.deltaTime,因为unscaledDeltaTime不受timeScale的影响,而Time.deltaTime受timeScale的影响,并且timeScale也影响不到Update的调用
5. Time.fixedDeltaTime
其代表物理更新的时间间隔,但这个是游戏内的物理固定时间间隔,并不是真实的物理世界的物理更新的时间间隔,其值可以在Unity中设置
默认是0.02s,即1秒50次的游戏内物理系统更新,它并不会受到timeScale 的影响
- 当timeScale == 1时
保持在0.02s
- 当timeScale == 0.5时
保持在0.02s
- 当timeScale == 2时
说明timeScale并不会影响到Time.fixedDeltaTime
6. Time.fixedUnscaledDeltaTime
字面意思看是FixedUpdate的更新间隔,且不受timeScale影响,但事实如此吗?
- 当timeScale == 1时
除了刚开始的时候不稳定,之后一直稳定在0.02s
- 当timeScale == 0.5时
稳定在了0.04s
- 当timeScale == 2时
稳定在了0.01s
- 当timeScale == 0时
变回了0.02s,这里属于特殊情况,后面再解释
从上面可以得出的关系有
当timeScale ==1 时,Time.fixedDeltaTime = Time.fixedUnscaledDeltaTime = 0.02
当timeScale == 0.5时, Time.fixedDeltaTime / 0.5 =Time.fixedUnscaledDeltaTime = 0.04
当timeScale == 2时,Time.fixedDeltaTime / 2 =Time.fixedUnscaledDeltaTime = 0.01
即得出 Time.fixedDeltaTime = Time.fixedUnscaledDeltaTime * Time.timeScale,且Time.fixedUnscaledDeltaTime受到timeScale的影响,timeScale越大,fixedUnscaledDeltaTime越小,timeScale越小,fixedUnscaledDeltaTime越大
7. 和FixedUpdate之间的关系
FixedUpdate是Mono的生命周期函数,用于进行物理的更新和计算,那么它的真实更新时间间隔是多少呢
我们依旧可以使用Time.realtimeSinceStartup来进行验证
- 当timeScale = 1 时
每2帧之间的差值大概在0.02s左右,等于此时的Time.fixedDeltaTime和Time.fixedUnscaledDeltaTime
- 当timeScale = 0.5 时
每2帧之间的差值大概在0.04s,等于此时的Time.fixedUnscaledDeltaTime
- 当timeScale = 2 时
每2帧之间的差值大概在0.01s,等于此时的Time.fixedUnscaledDeltaTime
- 当timeScale = 0 时
可以看到除了刚启动时的第一帧,之后FixedUpdate并没有走
从这里可以得出结论,FixedUpdate的真实更新的时间间隔就是Time.fixedUnscaledDeltaTime,而游戏内的物理更新的时间间隔是Time.fixedDeltaTime,并且FixedUpdate的更新受到timeScale 的影响,timeScale越大,FixedUpdate的更新频率越快,但是真实更新间隔越小;timeScale越小,FixedUpdate的更新频率越慢,但是真实更新间隔越大;当timeScale == 0 时,物理更新会被冻结
8. Time.time
这是自应用程序启动以来以秒为单位的时间,这是一个累计时间
那么它受到timeScale影响吗?
- 当timeScale = 1 时
每2帧之间的时间间隔大概是0.0015
- 当timeScale = 0.5 时
每2帧之间的时间间隔大概是0.00075
- 当timeScale = 2 时
每2帧之间的时间间隔大概是0.003
- 当timeScale = 0 时
一直是0
可以看到,当timeScale 改变时,每帧的间隔也就是Time.deltaTime在改变,从而影响了Time.time的累计,也就是说Time.time是每帧Time.deltaTime的叠加,受到timeScale 影响,这是一个游戏内时间的累计,当timeScale 为0时,其累计被冻结
那么它是否受到编辑器暂停影响呢?
编辑器暂停时的最后一帧的时间输出是7.84565
编辑器恢复后的第一帧的时间输出同样是7.86565
综上所述,编辑器暂停会影响到Time.time,编辑器暂停,它暂停累计,编辑器恢复,它也恢复
9. Time.unscaledTime
- 当timeScale = 1 时
每2帧之间的时间间隔大概是0.0015
- 当timeScale = 0.5 时
每2帧之间的时间间隔大概是0.0015
- 当timeScale = 2 时
每2帧之间的时间间隔大概是0.0015
- 当timeScale = 0 时
累计没有暂停,每2帧之间的时间间隔大概是0.0015
可以看到,当timeScale 改变时,每帧之间的时间间隔并没有改变,其值就是Time.unscaledDeltaTime,它就是Time.unscaledDeltaTime的一个时间累计,是一个真实的时间累计,但它还是根据帧来计算的,即同一帧内如果多次调用,输出的是一样的值,和Time.realtimeSinceStartup还是不同,具体放到下面讨论
那么它会被编辑器暂停影响吗?
暂停前一帧的时间是5.142294
取消暂停后,时间是从30.14599开始的
综上所述,Time.unscaledDeltaTime是不受编辑器暂停影响的,即使编辑器暂停,Time.unscaledDeltaTime也依旧在累计
10. Time.fixedTime
字面意思是Time.fixedDeltaTime的累计
- 当timeScale = 1 时
每2帧之间的间隔是0.02
- 当timeScale = 0.5 时
每2帧之间的间隔是0.02
- 当timeScale = 2 时
每2帧之间的间隔是0.02
- 当timeScale = 0 时
一直是0
从这里可以得知,timeScale 不会影响Time.fixedTime的累计,除了timeScale == 0 的情况,因为这时候FixedUpdate被冻结了
会受编辑器暂停影响吗?
暂停前最后一帧的时间是3.34
取消暂停后,是从3.36开始
综上所述,Time.fixedTime会受到编辑器暂停影响,编辑器暂停时,累计停止,编辑器重启,其累计重启
11. Time.fixedUnscaledTime
是Time.fixedUnscaledDeltaTime的累计
- 当timeScale = 1 时
每2帧之间的时间间隔大概是0.02
- 当timeScale = 0.5 时
每2帧之间的时间间隔大概是0.04
- 当timeScale = 2 时
每2帧之间的时间间隔大概是0.01
- 当timeScale = 0 时
这里放到了Update中测试
一直是0,因为FixedUpdate被冻结了
综上,Time.fixedUnscaledTime受到timeScale 的影响,因为Time.fixedUnscaledDeltaTime会被timeScale影响,所以其累计也会被影响
是否受编辑器暂停影响?
暂停前最后一帧的时间是5.741369
暂停回来后,直接从58.41098开始
综上,说明编辑器暂停不会影响Time.fixedUnscaledTime的累计
12. Time.realtimeSinceStartup
这个反应的是游戏开始以来真正的时间,不受timeScale 影响,不受编辑器暂停影响,和Time.unscaledTime 的区别在于,realtimeSinceStartup在一帧中如果多次调用时会继续累计的,而Time.unscaledTime不会
可以发现在同一帧中调用2次的情况下,realtimeSinceStartup也一直在更新
而Time.unscaledTime在一帧中调用多次,输出是一样的
13. timeScale = 0时,FixedUpdate为什么会被冻结
当timeScale = 0 时,deltaTime = 0,Time.time累计加的是0,相当于这时候Time.time一直没有更新,所以Time.fixedTime相较于Time.time一直没有机会差至少一个fixedDeltaTime,也就不会走到后面这一块从而执行FixedUpdate,只会一直走Update