做Unity也有一年多了,但项目中总没有一个方便使用的时间管理类,前段时间抽空把以前AS项目中的一个时间管理类改了一下,用了段时间,感觉还不错,分享给大家
这是一个单例类,适合整个项目的时间管理,从此让我们摆脱MonoBehaviour.Update函数
另外,由统一管理调用的,大家可能会觉得耗性能,这只是调用委托函数,即使一次循环调用上千个空方法,都不会卡顿的,主要是看方法内部的实现,大家都知道不要在Update里写大量逻辑,这里也是一样的道理,特别是循环调用的回调,要注意代码逻辑。
先贴用法,再贴代码
方法一、定时执行一次(基于毫秒)
doOnce(int delay, Handler method)
doOnce
doOnce
doOnce
这是一种重载写法,如果不懂重载,就要去补一下基础了,这里不再科普
T1,T2,T3在这里出现是因为项目中有些时候可能在我执行这个Handler回调时,想接收一些参数,这样就用到了。
无参用法:
TimerManager.instance.doOnce(3000,method); 3000毫秒后执行method
有参用法,比如有两个参数
TimerManager.instance.doOnce
3000毫秒后执行method,并把go,tf传递给method
这种用法相信很多人都懂了,如果不懂可以留言给我。
下面的方法,都是一样,都有四种重载方法,我在这里就不一一贴出来了,大家可以看后面的代码。
方法二、定时重复执行(基于毫秒)
doLoop(int delay, Handler method)
方法三、定时执行一次(基于帧率)
doFrameOnce(int delay, Handler method)
方法四、定时重复执行(基于帧率)
doFrameLoop(int delay, Handler method)
方法五、清理定时器
clearTimer(Handler method)
定时执行一次:只会执行一次,执行完成后会自动调用clearTimer
定时重复执行:会重复调用method回调,直到程序主动调用clearTimer
基于毫秒:以毫秒为间隔调用method
基于帧率:以帧速来调用,假设传1,1帧执行一次,传2,2帧执行一次
这是一个管理类,需要有调用方,那么我们需要调用他
我们每个项目中肯定有一个永远存在的继承自MonoBehaviour的类,在Update中写上:
foreach(IAnimatable animatable in TimerManager.timerList) {
animatable.AdvanceTime();
}
接下来贴代码
先贴继承类,这是一个用于方便写单例的基类
1 public abstract class PureSingletonwhere T : new() { 2 private static T _instance; 3 public static T instance{ 4 get{ 5 if(_instance == null){ 6 _instance = new T(); 7 } 8 return _instance; 9 } 10 } 11 }
这是正类 TimerManager
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using UnityEngine; 5 6 public delegate void Handler(); 7 public delegate void Handler(T1 param1); 8 public delegate void Handler (T1 param1, T2 param2); 9 public delegate void Handler (T1 param1, T2 param2, T3 param3); 10 11 public interface IAnimatable { 12 void AdvanceTime(); 13 } 14 15 /**时钟管理器[同一函数多次计时,默认会被后者覆盖,delay小于1会立即执行]*/ 16 public class TimerManager:PureSingleton , IAnimatable { 17 18 public static List timerList = new List (); 19 20 public TimerManager() { 21 timerList.Add(this); 22 } 23 24 private List _pool = new List (); 25 /** 用数组保证按放入顺序执行*/ 26 private List _handlers = new List (); 27 private int _currFrame = 0; 28 private uint _index = 0; 29 30 public void AdvanceTime() { 31 _currFrame++; 32 for(int i = 0; i < _handlers.Count; i++) { 33 TimerHandler handler = _handlers[i]; 34 long t = handler.userFrame ? _currFrame : currentTime; 35 if(t >= handler.exeTime) { 36 Delegate method = handler.method; 37 object[] args = handler.args; 38 if(handler.repeat) { 39 while(t >= handler.exeTime) { 40 handler.exeTime += handler.delay; 41 method.DynamicInvoke(args); 42 } 43 } else { 44 clear(handler.method); 45 method.DynamicInvoke(args); 46 } 47 } 48 } 49 } 50 51 private object create(bool useFrame, bool repeat, int delay, Delegate method, params object[] args) { 52 if(method == null) { 53 return null; 54 } 55 56 //如果执行时间小于1,直接执行 57 if(delay < 1) { 58 method.DynamicInvoke(args); 59 return -1; 60 } 61 TimerHandler handler; 62 if(_pool.Count > 0) { 63 handler = _pool[_pool.Count - 1]; 64 _pool.Remove(handler); 65 } else { 66 handler = new TimerHandler(); 67 } 68 handler.userFrame = useFrame; 69 handler.repeat = repeat; 70 handler.delay = delay; 71 handler.method = method; 72 handler.args = args; 73 handler.exeTime = delay + (useFrame ? _currFrame : currentTime); 74 _handlers.Add(handler); 75 return method; 76 } 77 78 /// /// 79 /// 定时执行一次(基于毫秒) 80 /// 81 /// 延迟时间(单位毫秒) 82 /// 结束时的回调方法 83 /// 回调参数 84 public void doOnce(int delay, Handler method) { 85 create(false, false, delay, method); 86 } 87 public void doOnce (int delay, Handler method, params object[] args) { 88 create(false, false, delay, method, args); 89 } 90 public void doOnce (int delay, Handler method, params object[] args) { 91 create(false, false, delay, method, args); 92 } 93 public void doOnce (int delay, Handler method, params object[] args) { 94 create(false, false, delay, method, args); 95 } 96 97 /// /// 98 /// 定时重复执行(基于毫秒) 99 /// 100 /// 延迟时间(单位毫秒) 101 /// 结束时的回调方法 102 /// 回调参数 103 public void doLoop(int delay, Handler method) { 104 create(false, true, delay, method); 105 } 106 public void doLoop (int delay, Handler method, params object[] args) { 107 create(false, true, delay, method, args); 108 } 109 public void doLoop (int delay, Handler method, params object[] args) { 110 create(false, true, delay, method, args); 111 } 112 public void doLoop (int delay, Handler method, params object[] args) { 113 create(false, true, delay, method, args); 114 } 115 116 117 /// 118 /// 定时执行一次(基于帧率) 119 /// 120 /// 延迟时间(单位为帧) 121 /// 结束时的回调方法 122 /// 回调参数 123 public void doFrameOnce(int delay, Handler method) { 124 create(true, false, delay, method); 125 } 126 public void doFrameOnce (int delay, Handler method, params object[] args) { 127 create(true, false, delay, method, args); 128 } 129 public void doFrameOnce (int delay, Handler method, params object[] args) { 130 create(true, false, delay, method, args); 131 } 132 public void doFrameOnce (int delay, Handler method, params object[] args) { 133 create(true, false, delay, method, args); 134 } 135 136 /// 137 /// 定时重复执行(基于帧率) 138 /// 139 /// 延迟时间(单位为帧) 140 /// 结束时的回调方法 141 /// 回调参数 142 public void doFrameLoop(int delay, Handler method) { 143 create(true, true, delay, method); 144 } 145 public void doFrameLoop (int delay, Handler method, params object[] args) { 146 create(true, true, delay, method, args); 147 } 148 public void doFrameLoop (int delay, Handler method, params object[] args) { 149 create(true, true, delay, method, args); 150 } 151 public void doFrameLoop (int delay, Handler method, params object[] args) { 152 create(true, true, delay, method, args); 153 } 154 155 /// 156 /// 清理定时器 157 /// 158 /// method为回调函数本身 159 public void clearTimer(Handler method) { 160 clear(method); 161 } 162 public void clearTimer (Handler method) { 163 clear(method); 164 } 165 public void clearTimer (Handler method) { 166 clear(method); 167 } 168 public void clearTimer (Handler method) { 169 clear(method); 170 } 171 172 private void clear(Delegate method) { 173 TimerHandler handler = _handlers.FirstOrDefault(t => t.method == method); 174 if(handler != null) { 175 _handlers.Remove(handler); 176 handler.clear(); 177 _pool.Add(handler); 178 } 179 } 180 181 /// 182 /// 清理所有定时器 183 /// 184 public void clearAllTimer() { 185 foreach (TimerHandler handler in _handlers) { 186 clear(handler.method); 187 clearAllTimer(); 188 return; 189 } 190 } 191 192 public static void RemoveTimerMgr(TimerManager timerMgr) { 193 timerList.Remove(timerMgr); 194 } 195 196 /// 197 /// 游戏自启动运行时间,毫秒 198 /// 199 public long currentTime { 200 get { return (long) (Time.time * 1000); } 201 } 202 203 /**定时处理器*/ 204 205 private class TimerHandler { 206 /**执行间隔*/ 207 public int delay; 208 /**是否重复执行*/ 209 public bool repeat; 210 /**是否用帧率*/ 211 public bool userFrame; 212 213 /**执行时间*/ 214 public long exeTime; 215 216 /**处理方法*/ 217 public Delegate method; 218 219 /**参数*/ 220 public object[] args; 221 222 /**清理*/ 223 224 public void clear() { 225 method = null; 226 args = null; 227 } 228 } 229 }
大家如果觉得好,多给我回复一下,刷刷人气 ^_^