Unity中的定時器與延時器

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

相關文章
相關標籤/搜索