简单的时间管理器
? ? 最近在做一個小Demo,發現有很多地方需要延時調用一個方法,或者是一段邏輯才能實現功能。總結起來我感覺最常用的有以下幾個。
1.定義 timeCounter 最簡單的一種
float timeCounter = 0; //定義一個時間計時器private void Update() {timeCounter += Time.deltaTime; //在update中調用 加上幀間隔時間if(timeCounter > 10){//TODO; //在這里寫上需要在 10 秒之后執行的邏輯} }?這種寫法雖然最為方便,但卻要一直在update中實時調用,當然你也可以加一個bool,控制流程,但仍需要時時刻刻去做判斷。不是一種好的寫法。如果只是為了實現一些簡單的功能,這種寫法還是挺好用的,簡單粗暴。
2.Invoke 延時調用
private void Start() {Invoke("ToDo",10); }private void ToDo() {//Do Something }這種寫法也挺簡單的,直接定義好邏輯然后在你想要調用的地方,直接 Invoke 就行了,但是有個問題,邏輯必須要額外的封裝到一個方法中,且調用的時候需要通過方法的 字符串名稱調用的。
3. Coroutines?協程 ?
//假如在游戲開始時,我需要延時10s做一件事情 private void Start() {StartCoroutine("ToDo"); }IEnumerator ToDo() {yield return new waitForSecond(10);//Do Something; }StartCoroutine用來開啟協程,StopCoroutine用來終止協程,注意參數必須是1???IEnumerator 類型的 方法字符串名稱 ,如上代碼所示。2??還可以這樣寫?StartCoroutine(ToDo()); ?但是這種方式 終止協程StopCoroutine(ToDo());有點不太好使,停不下來 ,原因還在尋找中。
這種寫法很實用,而且隨時開啟并隨時終止它,易于控制使用靈活。但是邏輯仍然需要額外封裝,方法多了略微會降低代碼的可讀性。而且不停的 new waitForScond ,在優化時也是一個需要處理的很大的消耗項。
4.TimeManager?
using System.Collections; using System.Collections.Generic; using UnityEngine; using System;//創建時間 Timer 類 public class Timer {Action action; //需要執行的事件public bool isEnd = false; //時間計時結束標志float timeCounter = 0; //時間計時器float endTime; //終止時間private Timer() { }public Timer(float time, Action action) //構造方法賦值{timeCounter = 0;endTime = time;this.action = action;}public void Update(float dt) //提供一個公開的 Update 方法 用來計時{timeCounter += dt;if (timeCounter >= endTime) //當時間計時器 加到 終止時間 的大小時,執行事件{action();isEnd = true; //標記isEnd = true;}} }//時間管理器。用來管理 Timer 類實例化出來的對象 public class TimeManager {//單例private static TimeManager instance;public static TimeManager Instance{get{if (instance == null){instance = new TimeManager();}return instance;}}List<Timer> timeList = new List<Timer>(); // 創建一個鏈表 用來存儲 Timer 對象//Invoke 公開方法 當外界調用時 傳入 timer:需要延時的時間。 action:需要執行的事件public void Invoke(float timer, Action action) {Timer time = new Timer(timer, action); //調用構造時,傳入參數timeList.Add(time); //將這個 Timer 對象添加進鏈表中}//提供給外界一個 Update 方法需要實時調用 public void Update(float dt){//for 循環遍歷 字典,執行 鏈表成員 的update 方法for (int i = 0; i < timeList.Count; i++){timeList[i].Update(dt);//當成員的某一個對象延時調用結束,則將此對象從鏈表中移除if (timeList[i].isEnd)。 {timeList.Remove(timeList[i]);}}}//提供給外界一個清空 鏈表的 方法public void Clear(){timeList.Clear();}}自己實現一個TimeManager類來管理Timer對象,當事件執行結束后,該事件所對應的Timer對象也被移除很方便。在使用時需要在一個游戲管理器中的update方法中調用一下 TimeManager.Instance.Update(Time.deltaTime);然后當需要延時調用時,可以像方法2那樣將方法封裝起來然后 Invoke(10,ToDo);?也可以使用Lambda表達式 Invoke(10,()=>{ ? //Do Someting??}); ? 的方式來實現。
還可以進一步實現 延時重復調用方法 InvokeRepeat()?,持續時間調用方法 ContinueExecute() ?,等;還可以進一步擴展Timer 對象的類型,使之在不同的游戲狀態下,執行不同的延時事件。可擴展性很高,配合游戲管理器來使用很方便。
?
個人見解,如有錯誤,敬請指正。
?
?
?
?
?
?
總結
- 上一篇: 计算机网络常用术语WWW,计算机网络常用
- 下一篇: 【无标题】STM32F407VGT6文件