Unity开发中常常会用定时器,例如Unity API中的Update(),LateUpadte(),协成等,要用的这些必须继承MonoBehaviour,我的做法是把所有的定时都集中到一个脚本里
public class MonoBehaviourAgent : MonoBehaviour { public MonoBehaviourAgent() { events = new Queue<UnityAction>(); UpdateAgentEvent += () => { lock (events) { while (events.Count > 0) { var action = events.Dequeue(); action.DefaultAction(); } } }; disposables = new List<IDisposable>(); } #region Unity Api Update public event UnityAction UpdateAgentEvent; public event UnityAction LateUpdateAgentEvent; public event UnityAction FixedUpdateAgentEvent; private readonly Queue<UnityAction> events; private List<IDisposable> disposables; private void Update() { UpdateAgentEvent.DefaultAction(); } private void LateUpdate() { LateUpdateAgentEvent.DefaultAction(); } private void FixedUpdate() { FixedUpdateAgentEvent.DefaultAction(); } private void OnDestroy() { foreach (var disposable in disposables) { disposable.Dispose(); } } #endregion #region 协成定时器 public void WariFixedTime(float fixedTime, UnityAction action) { StartCoroutine(wariFixedTime(fixedTime, action)); } IEnumerator wariFixedTime(float fixedTime, UnityAction action) { var waiter = new WaitForSeconds(fixedTime); while (true) { yield return waiter; action.DefaultAction(); } } public void WariFixedOneTime(float fixedTime, UnityAction action) { StartCoroutine(wariFixedOneTime(fixedTime, action)); } IEnumerator wariFixedOneTime(float fixedTime, UnityAction action) { var waiter = new WaitForSeconds(fixedTime); yield return waiter; action.DefaultAction(); } #endregion #region Threading.Timer /// <summary> /// 开启定时器(执行一次) /// </summary> /// <param name="milisecond">定时毫秒</param> /// <param name="action">回调函数</param> public void OneTimeTimerStart(int milisecond, UnityAction action) { OneTimeTimer oneTimeTimer = new OneTimeTimer(milisecond, () => { action.DefaultAction(); }); } /// <summary> /// 开启定时器 /// </summary> /// <param name="milisecond">定时毫秒</param> /// <param name="action">回调函数</param> public void PeriodicTimerStart(int milisecond, UnityAction action) { PeriodicTimer periodicTimer = new PeriodicTimer(milisecond, () => { action.DefaultAction(); }); } /// <summary> /// 开启定时器(执行一次) /// </summary> /// <param name="milisecond">定时毫秒</param> /// <param name="action">回到主线程调用</param> public void OneTimeTimerStartOnMainThread(int milisecond, UnityAction action) { OneTimeTimer oneTimeTimer = new OneTimeTimer(milisecond, () => { lock (events) { events.Enqueue(action); } }); } /// <summary> /// 开启定时器 /// </summary> /// <param name="milisecond">定时毫秒</param> /// <param name="action">回到主线程调用</param> public void PeriodicTimerStartOnMainThread(int milisecond, UnityAction action) { PeriodicTimer periodicTimer = new PeriodicTimer(milisecond, () => { lock (events) { events.Enqueue(action); } }); } /// <summary> /// 执行一次定时类 /// </summary> sealed class OneTimeTimer : IDisposable { static readonly HashSet<Timer> timers = new HashSet<Timer>(); private UnityAction action; private Timer timer; public OneTimeTimer(int dueTime, UnityAction action) { this.action = action; timer = new Timer(Tick, null, dueTime, -1); lock (timers) { timers.Add(timer); } } private void Tick(object state) { try { action.DefaultAction(); } finally { Unroot(); } } private void Unroot() { lock (timers) { if (timer != null) timers.Remove(timer); } if (timer != null) timer.Dispose(); } public void Dispose() { } } /// <summary> /// 执行循环定时类 /// </summary> sealed class PeriodicTimer : IDisposable { static readonly HashSet<Timer> timers = new HashSet<Timer>(); private UnityAction action; private Timer timer; public PeriodicTimer(int period, UnityAction action) { this.action = action; timer = new Timer(Tick, null, period, period); lock (timers) { timers.Add(timer); } } private void Tick(object state) { lock (this) { action.DefaultAction(); } } public void Dispose() { lock (timers) { if (timer != null) timers.Remove(timer); } if (timer != null) timer.Dispose(); } } #endregion }