一:目的異步
遊戲開發中,計時是一個常見的功能。好比技能的冷卻時間,角色的生命回覆等等this
通常的實現方法是經過協程或者Invoke,可是這樣並無統一管理全部的計時器,因此咱們須要一個管理器統一管理計時器的相關操做code
二:解決的問題及優勢協程
——註冊和註銷計時器
——獲得某一個計時器的倒計時剩餘時間
——設置全部倒計時同步或異步遊戲
三:使用方法圖片
——使用TimerMgr.Ins.XXX遊戲開發
TimerMgr.Ins.RegisterTimer(3, () => { Debug.Log("finish 1"); }, "", true); TimerMgr.Ins.RegisterTimer(4, () => { Debug.Log("finish 2"); }, "", true); TimerMgr.Ins.UnRegisterAllTimer(); TimerMgr.Ins.UnRegisterTimer("Timer1"); TimerMgr.Ins.GetRemainTime("Timer1");
四:代碼實現開發
using System.Collections.Generic; using UnityEngine; using System; /// <summary> /// 計時管理器 /// </summary> public class TimerMgr : MonoSingleton<TimerMgr> { //是否同步計時 private bool isSync = true; public bool IsSync { get { return isSync; } set { isSync = value; } } private List<TimerData> timerList = new List<TimerData>();//倒計時列表 private void Awake() { lastUpdateTime = Time.realtimeSinceStartup; } /// <summary> /// 註冊倒計時 /// </summary> public void RegisterTimer(float countdown, Action onFinish = null, string timerName = "", bool ignoreTimeScale = false) { TimerData timerData = new TimerData(countdown, onFinish, timerName, ignoreTimeScale); timerList.Add(timerData); } /// <summary> /// 註銷全部倒計時 /// </summary> public void UnRegisterAllTimer() { timerList.Clear(); } /// <summary> /// 註銷某一個倒計時 /// </summary> public void UnRegisterTimer(string name) { List<TimerData> unRegisterCache = new List<TimerData>(); foreach (var timer in timerList) { if (timer.name == name) { unRegisterCache.Add(timer); } } for (int i = unRegisterCache.Count - 1; i >= 0; i--) { timerList.RemoveAt(i); } } /// <summary> /// 獲得倒計時剩餘時間 /// </summary> public float GetRemainTime(string name) { foreach (var timer in timerList) { if (timer.name == name) { return timer.Timer; } } Debug.LogWarning("沒有註冊倒計時:" + name); return -1; } float lastUpdateTime;//上一次的時間 private void Update() { float realDeltaTime = Time.realtimeSinceStartup - lastUpdateTime; lastUpdateTime = Time.realtimeSinceStartup; if (isSync) { for (int i = 0; i < timerList.Count; i++) { timerList[i].UpdateTimer(timerList[i].ignoreTimeScale ? realDeltaTime : Time.deltaTime); if (timerList[i].isFinish) { timerList.Remove(timerList[i]); i--; } } } else { if (timerList.Count == 0) return; timerList[0].UpdateTimer(timerList[0].ignoreTimeScale ? realDeltaTime : Time.deltaTime); if (timerList[0].isFinish) { timerList.Remove(timerList[0]); } } } } /// <summary> /// 計時器的數據類 /// </summary> public class TimerData { //計時器 private float timer; public float Timer { get { return timer; } } public float countdown;//倒計時時間 public string name;//倒計時的名稱 public bool ignoreTimeScale;//是否忽略時間比例 public Action onFinish;//倒計時結束的回調 public bool isFinish;//是否完成倒計時 /// <summary> /// 初始化計時器 /// </summary> public TimerData(float countdown, Action onFinish, string name, bool ignoreTimeScale) { timer = countdown; this.countdown = countdown; this.onFinish = onFinish; this.name = name; this.ignoreTimeScale = ignoreTimeScale; } /// <summary> /// 更新倒計時 /// </summary> public void UpdateTimer(float deltaTime) { timer -= deltaTime; if (timer <= 0) { isFinish = true; onFinish?.Invoke(); } } }
圖片來源:http://www.coubai.com/ 網頁遊戲get