前言
项目体量过大时,在很多脚本用到了携程计时或者写在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);
});
如果这边文章对你写计时器思路有帮助的话,那就点下赞吧,谢谢!