unity实现延迟回调工具

一个实用的计时器,可以计时延迟调用和延迟重复次数调用。
可以自己封装成单例模式挂在GameObject上使用,或者在另一个behavior的Update里执行这个类的OnUpdate()方法再使用。
为了更加安全的使用,建议在销毁MonoBehaviour时清理一下对应的所有计时器。
或者调用时可选择传入回调所在的MonoBehaviour,这样就可以自动清理了。

using System.Collections; using System; using System.Collections.Generic; using UnityEngine; public static class DelayCall{private static List calltimes = new List(); private static Dictionary callsort = new Dictionary(); private static int countid = 0; /// /// 生成id/// /// The new identifier./// Call.private static int getNewId(CallObj call){countid++; if (countid >= int.MaxValue){countid = 1; }while (callsort.ContainsKey(countid)) countid++; call.callid = countid; callsort.Add(countid, call); return countid; }public static void ClearAll(){calltimes.Clear(); callsort.Clear(); }/// /// 删除延迟执行./// /// /// Call./// public static void remove(int callid){if (callid > 0 && callsort.ContainsKey(callid)){CallObj call = callsort[callid]; callsort.Remove(callid); if (call != null){calltimes.Remove((CallTimeObj)call); }}}public static int AddTime(float delayTime, object arg, int repeat = 1,Action call){var callobj = new CallTimeObj(); callobj.argsCall = call; callobj.arg = arg; callobj.repeat = repeat; callobj.time = Time.realtimeSinceStartup + delayTime; callobj.delayTime = delayTime; if (repeat == 0){callobj.isloop = true; }calltimes.Add(callobj); getNewId(callobj); return callobj.callid; }/// /// 添加延迟执行/// /// 回调方法/// 延迟时间/// 【unity实现延迟回调工具】重复回调次数/// 承载回掉函数的实例是否存在的判断/// 是否是唯一的方法/// 如果重复是否覆盖/// public static int AddTime(float delayTime, int repeat = 1, MonoBehaviour mn = null, bool isUnique = false, bool isReplace = false,Action call){if (isUnique){for (int i = 0; i < calltimes.Count; i++){CallTimeObj call2 = calltimes[i]; if (call2.mn == mn && call2.call == call){if (isReplace){call2.time = Time.realtimeSinceStartup + delayTime; }return call2.callid; }}}var callobj = new CallTimeObj(); callobj.call = call; callobj.isMN = (mn != null); callobj.mn = mn; callobj.repeat = repeat; callobj.time = Time.realtimeSinceStartup + delayTime; callobj.delayTime = delayTime; if (repeat == 0){callobj.isloop = true; }calltimes.Add(callobj); getNewId(callobj); return callobj.callid; }public static void OnUpdate(){//time callif (calltimes.Count != 0) for (int i = 0; i < calltimes.Count; ++i){CallTimeObj call = calltimes[i]; if (call.time <= Time.realtimeSinceStartup){if (call.isloop == false){call.repeat--; if (call.repeat <= 0){calltimes.RemoveAt(i); callsort.Remove(call.callid); --i; }else{//重新累加时间call.time += call.delayTime; }}else{call.time += call.delayTime; }if (!call.isMN || call.mn != null){try{if (call.argsCall != null){call.argsCall.Invoke(call.arg); if (call.isloop == false){if (call.repeat <= 0){call.arg = null; call.argsCall = null; call.mn = null; }}}else{call.call(); }}catch (Exception e){Debug.LogException(e); }}}}}private class CallObj{public Action call = null; public int frame; public bool isMN; public MonoBehaviour mn; public int callid = 0; }private class CallTimeObj : CallObj{public Action argsCall = null; public float time; public int repeat = 1; public float delayTime = 0; public object arg; public bool isloop = false; }}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    推荐阅读