前言
项目体量过大时,在很多脚本用到了携程计时或者写在update里面,不方便管理和代码阅读,很容易混淆,所以需要一个计时任务管理器来统一控制计时器模块,便于修改、管理。计时器有很多种写法,我这里写的是适用于我当前做的项目,并不适用于所有项目,写在这里只是起记录作用,有相同需求的可以作为参考。
计时器归根结底底层逻辑还是用携程或者update,但是怎么样写才能更方便统一管理呢?
核心代码
还有循环计时、计时完成CallBack功能待优化,等后续用到这些功能再扩展。目前只用于普通计时。
public class Timer{private Action<float> OnFinished;private float delyaTime;private bool isLoop;private bool isFinish;private float curTime = 0;/// <summary>/// 计时器/// </summary>/// <param name="onFinished">回调</param>/// <param name="delyaTime">计时时间</param>/// <param name="isLoop">是否循环</param>public Timer(Action<float> onFinished, float delyaTime, bool isLoop){OnFinished = onFinished;this.delyaTime = delyaTime;this.isLoop = isLoop;this.isFinish = false;}public bool IsFinish => isFinish;private void StopTimer() => isFinish = true;public void UpdataTimer(){if (isFinish) return;if (curTime < delyaTime) curTime += Time.deltaTime;var t = curTime.ToString("f0");if (t == delyaTime.ToString()){if (!isLoop){StopTimer();}}OnFinished?.Invoke(float.Parse(t));}}
内部调用代码:
/// <summary>/// 内部类/// </summary>public class TimeHandle : MonoBehaviour{private List<Timer> updateTimersList = new List<Timer>();public Timer TimerHandle(Action<float> onFinishef, float delayTime, bool isLoop = false){Timer timer = new Timer(onFinishef, delayTime, isLoop);updateTimersList.Add(timer);return timer;}public void Update(){if (updateTimersList.Count == 0) return;for (int i = 0; i < updateTimersList.Count; i++){if (updateTimersList[i].IsFinish){updateTimersList.RemoveAt(i);}else{updateTimersList[i].UpdataTimer();}}}}
管理模块:
/// <summary>
/// 计时任务管理模块
/// </summary>
public class AppTimeMoudle : AppMoudle
{public TimeHandle Timer;public override void OnInit(){GameObject timer = new GameObject("AppTimeMoudle");Timer = timer.AddComponent<TimeHandle>();GameObject.DontDestroyOnLoad(timer);}public override void OnQuit() {GameObject.Destroy(Timer.gameObject);}
}
使用方法
调用TimerHandle时,通过对返回参数进行加减或者对比操作来实现正反计时。
(msg) =>
{var time = 2.0f;SimApp.AppMoudle<AppTimeMoudle>().Timer.TimerHandle((o) =>{_errorTip.text = msg;_errorTip.gameObject.SetActive(true);if (time - o <= 0){_errorTip.gameObject.SetActive(false);}},time,false);Debug.LogError(msg);
});
如果这边文章对你写计时器思路有帮助的话,那就点下赞吧,谢谢!