定时任务类:
#region 时间定时任务 public class PETimeTask { ////// 全局任务ID /// public string taskID; ////// 首次延迟时间 /// public float firstDelayTime; ////// 回调函数 /// public Action callback; ////// 之后每次循环调用延迟的时间 /// public float delayTime; ////// 执行次数 /// public int count; public PETimeTask(Action callback, float firstDelayTime, float delayTime, int count) { this.taskID = Guid.NewGuid().ToString(); this.callback = callback; this.firstDelayTime = firstDelayTime; this.delayTime = delayTime; this.count = count; } } public enum PETimeTaskUnit { Millisecond, Second, Minute, Hour, Day } #endregion #region 帧定时任务 public class PEFrameTask { ////// 全局任务ID /// public string taskID; ////// 首次延迟帧数 /// public int firstDelayFrame; ////// 回调函数 /// public Action callback; ////// 之后每次循环调用的延迟帧数 /// public int delayFrame; ////// 执行次数 /// public int count; public PEFrameTask(Action callback, int firstDelayFrame, int delayFrame, int count) { this.taskID = Guid.NewGuid().ToString(); this.callback = callback; this.firstDelayFrame = firstDelayFrame; this.delayFrame = delayFrame; this.count = count; } } #endregion
任务管理类:
using Assets.Scripts; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class TimerSys : MonoBehaviour { public static TimerSys Instance; //定时时间任务列表 private ListtaskTimeList = new List (); //定时帧任务列表 private List taskFrameList = new List (); //游戏开始到现在的帧数 public int frameCount; public void Awake() { Debug.Log("初始化成功"); if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else Destroy(gameObject); } private void Update() { CheckTimeTask(); CheckFrameTask(); } /// /// 检测时间定时任务 /// private void CheckTimeTask() { frameCount++; for (int i = 0; i < taskTimeList.Count; i++) { PETimeTask task = taskTimeList[i]; if (Time.realtimeSinceStartup * 1000 > task.firstDelayTime) { if (task.callback != null) task.callback.Invoke(); //移除已经完成的任务 if (task.count == 1) { taskTimeList.RemoveAt(i); i--; } else { if (task.count != 0) task.count--; task.firstDelayTime += task.delayTime; } } } } ////// 检测帧定时任务 /// private void CheckFrameTask() { for (int i = 0; i < taskFrameList.Count; i++) { PEFrameTask task = taskFrameList[i]; if (frameCount > task.firstDelayFrame) { if (task.callback != null) task.callback.Invoke(); if (task.count == 1) { taskFrameList.RemoveAt(i); i--; } else { if (task.count != 0) task.count--; task.firstDelayFrame += task.delayFrame; } } } } #region 时间定时任务 ////// 添加定时任务 /// /// 回调函数 /// 第一次延迟时间 /// 以后每次调用的间隔时间 /// 时间单位 /// 执行次数,0表示一直执行 ///返回任务ID public string AddTimeTask(Action callback, float firstDelay, float delayTime, PETimeTaskUnit timeUnit = PETimeTaskUnit.Millisecond, int count = 1) { if (timeUnit != PETimeTaskUnit.Millisecond) { switch (timeUnit) { case PETimeTaskUnit.Second: firstDelay = firstDelay * 1000; delayTime = delayTime * 1000; break; case PETimeTaskUnit.Minute: firstDelay = firstDelay * 1000 * 60; delayTime = delayTime * 1000 * 60; break; case PETimeTaskUnit.Hour: firstDelay = firstDelay * 1000 * 60 * 60; delayTime = delayTime * 1000 * 60 * 60; break; case PETimeTaskUnit.Day: firstDelay = firstDelay * 1000 * 60 * 60 * 24; delayTime = delayTime * 1000 * 60 * 60 * 24; break; default: Debug.Log("时间格式错误"); break; } } float destTime = Time.realtimeSinceStartup * 1000 + firstDelay; PETimeTask timeTask = new PETimeTask(callback, destTime, delayTime, count); taskTimeList.Add(timeTask); return timeTask.taskID; } ////// 移除任务 /// /// 任务的GUID ///返回是否有该任务 public bool DeleteTimeTask(string taskID) { for (int i = 0; i < taskTimeList.Count; i++) { if (taskTimeList[i].taskID.Equals(taskID)) { taskTimeList.RemoveAt(i); return true; } } return false; } ////// 替换任务 /// ///是否替换成功 public bool ReplaceTimeTask(string taskID, Action callback, float firstDelayTime, float delayTime, PETimeTaskUnit timeUnit = PETimeTaskUnit.Millisecond, int count = 1) { //新的任务 if (timeUnit != PETimeTaskUnit.Millisecond) { switch (timeUnit) { case PETimeTaskUnit.Second: firstDelayTime = firstDelayTime * 1000; delayTime = delayTime * 1000; break; case PETimeTaskUnit.Minute: firstDelayTime = firstDelayTime * 1000 * 60; delayTime = delayTime * 1000 * 60; break; case PETimeTaskUnit.Hour: firstDelayTime = firstDelayTime * 1000 * 60 * 60; delayTime = delayTime * 1000 * 60 * 60; break; case PETimeTaskUnit.Day: firstDelayTime = firstDelayTime * 1000 * 60 * 60 * 24; delayTime = delayTime * 1000 * 60 * 60 * 24; break; default: Debug.Log("时间格式错误"); break; } } float destTime = Time.realtimeSinceStartup * 1000 + firstDelayTime; PETimeTask newTimeTask = new PETimeTask(callback, destTime, delayTime, count); //替换 for (int i = 0; i < taskTimeList.Count; i++) { if (taskTimeList[i].taskID.Equals(taskID)) { taskTimeList[i] = newTimeTask; return true; } } return false; } #endregion #region 帧定时任务 ////// 添加定时任务 /// /// 回调函数 /// 第一次延迟时间 /// 以后每次调用的间隔时间 /// 执行次数,0表示一直执行 ///返回任务ID public string AddFrameTask(Action callback, int firstDelayFrame, int delayFrame, int count = 1) { PEFrameTask frameTask = new PEFrameTask(callback, frameCount + firstDelayFrame, delayFrame, count); taskFrameList.Add(frameTask); return frameTask.taskID; } ////// 移除任务 /// /// 任务的GUID ///返回是否有该任务 public bool DeleteFrameTask(string taskID) { for (int i = 0; i < taskFrameList.Count; i++) { if (taskFrameList[i].taskID.Equals(taskID)) { taskFrameList.RemoveAt(i); return true; } } return false; } ////// 替换任务 /// ///是否替换成功 public bool ReplaceFrameTask(string taskID, Action callback, int firstDelayFrame, int delayFrame, int count = 1) { PEFrameTask newFrameTask = new PEFrameTask(callback, frameCount + firstDelayFrame, delayFrame, count); for (int i = 0; i < taskFrameList.Count; i++) { if (taskFrameList[i].taskID.Equals(taskID)) { taskFrameList[i] = newFrameTask; return true; } } return false; } #endregion }
使用:
private void ClickAddBtn() { taskID = TimerSys.Instance.AddFrameTask(()=> { Debug.Log(TimerSys.Instance.frameCount); Debug.Log(taskID); },100,50,0); } private void ClickDelBtn() { TimerSys.Instance.DeleteFrameTask(taskID); } private void ClickRepBtn() { TimerSys.Instance.ReplaceFrameTask(taskID,FuncB,1000,2000); }
可以参考此网站:Unity 工具类 之 简单定时任务系统 TimerTaskSystem 的实现_仙魁XAN-CSDN博客_unity 定时任务