Unity 游戏暂停和继续
Time.timeScale 时间缩放
在 Unity 中,利用 Time.timeScale=0 可以暂停游戏,Time.timeScale=1 恢复正常,
但这是作用于整个游戏的设置,不单单是当前的场景,所以在需要的时候重置回 Time.timeScale=1。
当然,也可以使用 Time.timeScale 来做游戏1倍、2倍的整体加速,以及0.5倍的整体减速。
Time.timeScale 影响因素
-
timeScale 不影响 Update 和 LateUpdate,会影响 FixedUpdate
-
timeScale 不影响 Time.realtimeSinceStartup,会影响 Time.timeSinceLevelLoad 和 Time.time
-
timeScale 不影响 Time.fixedDeltaTime 和 Time.unscaleDeltaTime,会影响 Time.deltaTime
将 Time.timeScale 设置为 0 会暂停所有和帧率无关的事情:
这些主要是指所有的物理事件和依赖时间的函数、刚体力和速度等,而且 FixedUpdate (不是Update)会受到影响,会被暂停,即 timeScale =0 时将不会调用 FixedUpdate 函数。
但是,Update 和 LateUpdate 函数本身的执行是不会受 Time.timeScale 影响的。
Update 依赖的是机器,它调用的次数和你机器渲染的速度一样(一些特殊情况除外);性能高的机器,帧率高,Update 函数执行次数也就多。
因此,当使用Time.timeScale = 0 时,所有和时间有关的事情都被暂停了。因为 Time.timeScale 为 0 时,Time.deltaTime 将为 0。
这也就意味着,如果你使用 Time.deltaTime 来控制旋转和位移等属性,那么 Time.timeScale = 0 也将使这些物体停止运动。
所以游戏看起来是被冻结了,但是,我们的游戏仍在渲染,也就是说 Update 函数仍在执行。
Time.timeScale 影响测试
1 using UnityEngine; 2 3 public class TimeScaleTest : MonoBehaviour 4 { 5 void Update() 6 { 7 if (Input.GetKeyDown(KeyCode.P)) Time.timeScale = 0; 8 if (Time.timeScale == 0) 9 { 10 print("Update"); 11 12 print("Time.time:" + Time.time); 13 print("Time.timeSinceLevelLoad:" + Time.timeSinceLevelLoad); 14 print("Time.realtimeSinceStartup:" + Time.realtimeSinceStartup); 15 16 print("Time.deltaTime:" + Time.deltaTime); 17 print("Time.fixedDeltaTime:" + Time.fixedDeltaTime); 18 print("Time.unscaledDeltaTime:" + Time.unscaledDeltaTime); 19 } 20 } 21 22 void LateUpdate() 23 { 24 if (Time.timeScale == 0) print("LateUpdate"); 25 } 26 27 void FixedUpdate() 28 { 29 if (Time.timeScale == 0) print("FixedUpdate"); 30 } 31 }
分别对里面的部分代码进行注释,测试结果如下:
当 timeScale 等于 0 时:
Update 和 LateUpdate 可以执行,FixedUpdate 不能执行
Time.realtimeSinceStartup 依然在增加,Time.timeSinceLevelLoad 和 Time.time 都没有变化
Time.fixedDeltaTime 不变,Time.deltaTime 变为 0,Time.unscaleDeltaTime 就像游戏正常速度运行下的 Time.deltaTime
总结
当想代码受 timeScale 控制时(如暂停、加速),可以把代码放在 FixedUpdate 中,又或者跟 Time.time 或 Time.deltaTime 扯上关系;
否则,可以用 Time.realtimeSinceStartup(类似正常状态下的Time.time) 和 Time.unscaleDeltaTime(类似正常状态下的Time.deltaTime)。
如果游戏暂停以后想在暂停界面上继续播放一些不受 Time.timeScale 影响的动画或者粒子特效,就要用 Time.realtimeSinceStartup 去单独恢复他们,还有声音部分也需要单独恢复 timeScale。
当然也可以放弃 Time.deltaTime 方法,自己实现两个函数:OnPauseGame 和 OnResumeGame。这种方法扩展性强,但是写起来可能会比较繁琐。
*** | 以上内容仅为学习参考、学习笔记使用 | ***