大家好,我是阿趙。
這期來說一下Unity的TimeScale。
一、前言
??Unity提供了Time這個類,來控制時間。其實我自己倒是很少使用這個Time,因為做網絡同步的游戲,一般是需要同步服務器時間,所以我比較多是在使用System.DateTime獲取系統時間,再定一個時間間隔和服務器同步當前時間,來維持一個客戶端和服務器的時間同步。
??不過Unity的Time方法也是有比較有用的時候,特別是Time.timeScale時間縮放這個屬性,它可以整體的加快或者減慢甚至暫停Unity里面動畫播放。
??不過這個TimeScale,也是會引起一些問題的,所以在使用之前,必須對它的影響范圍做一個詳細了解。
二、Demo
??TimeScale對Unity的所有動畫組件都是起作用的,包括了Animation、Animator、粒子發射器等。接下來看看它對腳本運行的影響。
??這里寫一個簡單的Demo,實際看看TimeScale的變化時,一些我們比較關心的方法調用有什么影響。
using UnityEngine;public class TestTimeScale : MonoBehaviour
{private float passTime = 0;private float fixedPassTime = 0;private float updateTime = 0;private float fixedUpdateTime = 0;private float lateUpdateTime = 0;private float[] timeArray = new float[] { 0, 0.1f, 1, 3 };// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){passTime += Time.deltaTime;updateTime += 1;}void FixedUpdate(){fixedPassTime += Time.fixedDeltaTime;fixedUpdateTime += 1;}private void LateUpdate(){lateUpdateTime += 1;}void OnGUI(){GUILayout.BeginHorizontal();GUILayout.Box(Time.timeScale + "");for(int i = 0;i<timeArray.Length;i++){if(OneButton(timeArray[i] + "x")){Time.timeScale = timeArray[i];}}GUILayout.EndHorizontal();GUILayout.Label("Time.time:"+Time.time);GUILayout.Label("passTime:" + passTime);GUILayout.Label("fixedPassTime:" + passTime);GUILayout.Label("updateTime:" + updateTime);GUILayout.Label("fixedUpdateTime:" + fixedUpdateTime);GUILayout.Label("lateUpdateTime:" + lateUpdateTime);GUILayout.Label("Time.deltaTime:" + Time.deltaTime);GUILayout.Label("Time.fixedDeltaTime:" + Time.fixedDeltaTime);GUILayout.Label("Time.fixedTime:" + Time.fixedTime);GUILayout.Label("Time.fixedUnscaledDeltaTime:" + Time.fixedUnscaledDeltaTime);GUILayout.Label("Time.realtimeSinceStartup:" + Time.realtimeSinceStartup);}private bool OneButton(string content){return GUILayout.Button(content, GUILayout.Width(100), GUILayout.Height(40));}
}
??運行demo,會看到上面有幾個調整TimeScale的按鈕,分別把TimeScale設置成0、 0.1 、1 、3。然后下面有一些當前數值的變化顯示。
三、分析
1、Update類
1.Update
??通過觀察demo里面的updateTime 可以發現,Update方法的調用頻率,是不會受到TimeScale的變化的影響的。
2.FixedUpdate
??通過觀察demo里面的fixedUpdateTime 可以發現,FixedUpdate方法是受到TimeScale影響的,當TimeScale變成0的時候,值就不會增長了,當TimeScale值變大那時,調用的頻率也會變快。
3.LateUpdate
??通過觀察demo里面的lateUpdateTime 可以發現,LateUpdate方法調用不受TimeScale的影響。
2、時間運行類
1.Time.time
??這個時間是從開始游戲到當前幀開始的時間,從demo運行可以看出,這個時間是會受到TimeScale的影響的,當TimeScale變成0的時候,它就不會增長了。
2.Time.fixedTime
??這個時間是從游戲開始運行到最后一次FixedUpdate方法調用的時間,從上面可以指定,FixedUpdate是受到TimeScale的影響的,所以,Time.fixedTime同樣也會受到TimeScale的影響。
3.Time.realtimeSinceStartup
??這個時間是從游戲開始運行到當前的實際時間。從demo可以看出,這個時間是不會受到TimeScale的影響的。所以如果想做一個不受TimeScale影響的計時器,可以使用這個。不過我還是更習慣于使用系統時間。
3、時間間隔類
1.Time.deltaTime
??這個時間是從上一幀到當前幀所過的時間。我們經常會使用speedTime.deltaTime來做一些準確限制速度的程序動畫。
??從demo可以看出,Time.deltaTime是會受到TimeScale的影響的,TimeScale的值越大,Time.deltaTime的值也就越大。所以通過在UpDate方法里面計算speedTime.deltaTime來做動畫時,當調大了TimeScale的值,那么動畫的速度也會變快。
2.Time.fixedDeltaTime
??從demo可以看出,Time.fixedDeltaTime是不會受到TimeScale的影響的,它默認是0.02,然后我們調節TimeScale的值,Time.fixedDeltaTime是不會變化的。
??值得注意的是,上面列舉的所有參數,都是只讀的,但是Time.fixedDeltaTime卻是可讀寫的。這個是非常有意義的事情來的。如果我們使用speedTime.deltaTime來做動畫,動畫會跟隨這TimeScale變快,但如果我們有一部分動畫的速度不想跟隨著TimeScale變化,那么就可以用speedTime.fixedDeltaTime來計算。而且我們還可以自己調節fixedDeltaTime的值,來單獨控制這部分動畫的快慢。