JavaScript中的定時器與延時器,分別是 setInterval、setTimeout,對應的清理函數是:clearInterval、clearTimeout。函數
而在Unity中,則分別是:Invoke、InvokeRepeating和取消延遲調用 CancelInvokespa
延遲調用設計
void Invoke(string methodName, float time);code
重複延遲調用blog
void InvokeRepeating(string methodName, float time, float repeatRate); 遊戲
在 time 秒 後調用 methodName 方法,而後每 repeatRate 秒 重複調用。ip
上面二個方法有什麼用處呢?我想到的應用場景就是,在遊戲主界面顯示當前遊戲的延遲 —— 幾乎成爲遊戲的標配了。string
爲了設計不至於太過複雜,我直接採用了定時器不斷的Ping,每隔幾秒就Ping一次,並給定每一次 Ping 一個超時上限。it
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PingTool : MonoBehaviour { // 最大嘗試ping的次數 private static int nMaxTryNum = 10; // 檢測頻率 private static float nCheckInterval = 3f; // 須要 ping 的 IP private static string strRemoteIP = ""; private static PingTool pingTool; public static void CreatePing(string strIP) { if (string.IsNullOrEmpty(strIP)) return; if (pingTool != null) { Debug.Log("Please Stop Ping Before."); return; } strRemoteIP = strIP; // 複用組件,避免頻繁的建立和銷燬組件 GameObject go = GameObject.Find("PingTool"); if (go == null) { go = new GameObject("PingTool"); DontDestroyOnLoad(go); } pingTool = go.AddComponent<PingTool>(); } public static void StopPing() { if (pingTool != null) { pingTool.CancelInvoke(); Destroy(pingTool); } } public static void SetCheckInterval(float value) { nCheckInterval = value; } private void Start() { InvokeRepeating("Execute", 0, nCheckInterval); } private void Execute() { if (pingTool == null) return; StartCoroutine(PingConnect()); } private void Destroy() { strRemoteIP = ""; nCheckInterval = 1.0f; pingTool = null; } private IEnumerator PingConnect() { if (pingTool != null) { Ping ping = new Ping(strRemoteIP); int nTryNum = 0; while (!ping.isDone) { yield return new WaitForSeconds(0.2f); // Ping Fail if (nTryNum++ > nMaxTryNum) { yield break; } } if (ping.isDone) { int nDelayTime = ping.time; Debug.Log("nDelayTime : " + nDelayTime.ToString() + "\t" + Time.time); } else { // 延時超過 2000 毫秒 } } } }
上面的例子每0.2秒檢測一次 Ping 是否結束,最多十次檢測,也就是2秒超時的時長。每3秒再檢測一次,上面示例代碼能夠再添加一個 callbackio