众所周知,在Unity里面开启协程会有消耗,有时候就算我们只需要用到一个简单的计时器,必须开一个协程或者自己写一个计时器。这里提供了一个通用的计时器类,里面还实现了内存池管理,使用完的计时器回收备用。
使用方法:只需负责调用即可,内部会自动回收。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class GlobalTimer : MonoBehaviour
{
private static GlobalTimer instance;
public static GlobalTimer Instance
{
get
{
if (!instance)
{
instance = GameObject.FindObjectOfType
();
}
if (!instance)
{
GameObject obj = new GameObject(typeof(GlobalTimer).ToString());
instance = obj.AddComponent
();
}
return instance;
}
}
//正在使用的TimerData
private List
mUseTimerDatas = new List
();
//空闲的TimerData
private List
mNotUseTimerDatas = new List
(); //尝试从空闲池中取一个TimerData private TimerData GetTimerData(bool isAdd = true) { TimerData data = null; if (mNotUseTimerDatas.Count <= 0) { data = new TimerData(); } else { data = mNotUseTimerDatas[0]; mNotUseTimerDatas.RemoveAt(0); } mUseTimerDatas.Add(data); return data; } //创建一个计时器 public TimerData AddTimer(float _duration, Action endCallBack, bool _isIgnoreTime = false) { TimerData data = GetTimerData(); data.Init(_duration, endCallBack, _isIgnoreTime); return data; } //创建一个重复型计时器 public TimerData AddIntervalTimer(float _duration, float _interval, Action _endCallBack, Action
_intervalCallBack, bool _isIgnoreTime = false) { TimerData data = GetTimerData(); data.Init(_duration, _endCallBack, _isIgnoreTime, _interval, _intervalCallBack); return data; } protected void Clear(TimerData data) { if (mUseTimerDatas.Remove(data)) { mNotUseTimerDatas.Add(data); } else { Debug.LogWarning("GlobalTimer not find TimerData"); } } #region 测试代码 void Start() { TimerData td1 = GlobalTimer.Instance.AddTimer(5, () => { Debug.Log("5秒后调用该方法1"); }); TimerData td2 = GlobalTimer.Instance.AddIntervalTimer(5, 1, () => { Debug.Log("5秒后调用该方法2"); }, (float remainTime) => { Debug.Log("每一秒调用执行此处:剩余时间" + remainTime); } ); } #endregion void Update() { for (int i = 0; i < mUseTimerDatas.Count; ++i) { if (!mUseTimerDatas[i].Update()) { //没更新成功,mUseTimerDatas长度减1,所以需要--i --i; } } } public class TimerData { //持续时间 private float mDuration; //重复间隔 private float mInterval; //结束回调 private Action mEndCallBack; //每次重复回调 private Action
mIntervalCallBack; //是否忽略时间 private bool isIgnoreTime; //计时器 private float mRunTime; //间隔计时器 private float mRunIntervalTime; //初始化 public void Init(float _duration, Action _endCallBack, bool _isIgnoreTime = false, float _interval = -1f, Action
_intervalCallBack = null) { mDuration = _duration; mInterval = _interval; mEndCallBack = _endCallBack; mIntervalCallBack = _intervalCallBack; isIgnoreTime = _isIgnoreTime; mRunTime = 0; mRunIntervalTime = 0; } //更新 public bool Update() { float deltaTime = isIgnoreTime ? Time.unscaledDeltaTime : Time.deltaTime; mRunTime += deltaTime; mRunIntervalTime += deltaTime; if (mIntervalCallBack != null) { if (mRunIntervalTime >= mInterval) { mRunIntervalTime -= mInterval; mIntervalCallBack(mDuration - mRunTime); } } if (mRunTime >= mDuration) { if (mEndCallBack != null) { mEndCallBack(); } Clear(); return false; } return true; } public void Clear() { instance.Clear(this); } public void AddEndCallBack(Action _endCallBack) { mEndCallBack += _endCallBack; } } }