馬三最近在做一款游戲的時候涉及到了“加速”和“暫停”這兩個功能,我第一時間就想到了應該用 Time.timeScale。當暫停的時候,設置timeScale = 0,當需要加速的時候,將 timeScale 設置為 n 倍即可。但是代碼寫到一般的時候,我就有些發懵,當 timeScale 數值被改變的時候,Update 、LateUpdate、FixedUpdate 是否還是安裝之前的頻率來執行呢?當 timeScale = 0時,Update 是不是會不執行了?
一、之前錯誤的認知
在這之前我一直認為:
- Time.timeScale可以控制Update 和LateUpdate 的執行速度。
- Time.timeScale=1時,Update、LateUpdate、FixedUpdate 都按正常的時間來執行。
- Time.timeScale=2時,Update和 LateUpdate的執行速度是之前的2倍,而FixedUpdate還是按正常時間來執行。
后來看到了雨松的博客,才知道上面的結論是錯誤的。因此,我通過做了一個簡單的測試,終於弄清了 timeScale 和 Update 、LateUpdate、FixedUpdate 之間的關系。
二、實驗與正確結論
還是先上一下實驗的代碼:
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 public class TimeManager : MonoBehaviour { 6 7 private float timer = 0f; 8 // Use this for initialization 9 void Start() { 10 timer = Time.realtimeSinceStartup; 11 } 12 13 // Update is called once per frame 14 void Update() { 15 if (Input.GetKeyDown(KeyCode.Alpha0)) { 16 Time.timeScale = 0; 17 } 18 if (Input.GetKeyDown(KeyCode.Alpha1)) { 19 Time.timeScale = 1; 20 } 21 if (Input.GetKeyDown(KeyCode.Alpha2)) { 22 Time.timeScale = 2; 23 } 24 Debug.Log("----------------------------"); 25 Debug.Log("Update: " + Time.deltaTime); 26 Debug.Log("Time.time: " + Time.time); 27 } 28 29 void LateUpdate() { 30 Debug.Log("----------------------------"); 31 Debug.Log("LateUpdate " + Time.deltaTime); 32 Debug.Log("Time.time: " + Time.time); 33 } 34 35 void FixedUpdate() { 36 Debug.Log("----------------------------"); 37 Debug.Log("FixedUpdate: " + Time.fixedDeltaTime); 38 Debug.Log("Time.time: " + Time.time); 39 } 40 41 }
當按下鍵盤上的 0~2 鍵時,將會分別設置 Time.timeScale 為 0~2。
設置 Time.timeScale 為 0 將會暫停所有和幀率無關的事情。這些主要是指所有的物理事件和依賴時間的函數、剛體力和速度等,而且 FixedUpdate 會被暫停(不是Update),因為FixedUpdate函數是根據時間來進行更新的。
但是,Update 函數本身的執行是不會受 Time.timeScale 的影響的。Update 是依賴你的機器的,它的調用次數和你的機器渲染一樣快慢(一些特殊情況除外);性能高的機器,幀率高,Update 函數執行次數也就多。因此,當使用 Time.timeScale = 0 時,游戲看起來是被凍結了,這是因為所有和時間有關的事情都被暫停了。但是,我們的游戲仍在渲染,也就是說 Update 函數仍在執行。無論 Time.timeScale 等於多少,Update 和 LateUpdate 都會去執行。所有的動畫都是基於時間來的,因為Time.timeScale = 0了,所以 Time.time 也就不會在變化了。當 Time.timeScale 為 0 時,Time.deltaTime 將為 0。這意味着,如果你使用 Time.deltaTime 來控制旋轉和位移等,那Time.timeScale = 0 也將使這些物體停止運動。
Time.timeScale 還會影響 Time.time 的時間,比如 Time.timeScale = 2 的話,那么 Time.time 的增長速度也會變成 2 倍速度。如果你想取到游戲的實際時間,那么使用Time.timeSinceLevelLoad 就可以,前提是必須在 Awake() 方法以后再取,如果在 Awake() 方法里面取 Time.realtimeSinceStartup 會取出一個錯誤的值,在 Start 方法里面取的話就正常了。如果游戲暫停以后想在暫停界面上繼續播放一些不受 Time.timeScale 影響的動畫,那么我們就需要用到 Time.realtimeSinceStartup。
總之一句話 Time.timeScale 影響的是 Unity 的游戲時間縮放比例。Unity 里面所有跟時間有關系的東西都是根據 timeScale 來演算的。
本篇博客中測試工程的開源地址:點我點我!
作者:馬三小伙兒
出處:http://www.cnblogs.com/msxh/p/6413577.html
請尊重別人的勞動成果,讓分享成為一種美德,歡迎轉載。另外,文章在表述和代碼方面如有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論!