Unity基于C#的时间管理类(TimerManager)

做Unity也有一年多了,但项目中总没有一个方便使用的时间管理类,前段时间抽空把以前AS项目中的一个时间管理类改了一下,用了段时间,感觉还不错,分享给大家

 

这是一个单例类,适合整个项目的时间管理,从此让我们摆脱MonoBehaviour.Update函数

另外,由统一管理调用的,大家可能会觉得耗性能,这只是调用委托函数,即使一次循环调用上千个空方法,都不会卡顿的,主要是看方法内部的实现,大家都知道不要在Update里写大量逻辑,这里也是一样的道理,特别是循环调用的回调,要注意代码逻辑。

 

先贴用法,再贴代码

 

方法一、定时执行一次(基于毫秒)

doOnce(int delay, Handler method)

doOnce<T1>(int delay, Handler<T1> method, params object[] args)

doOnce<T1, T2>(int delay, Handler<T1, T2> method, params object[] args)

doOnce<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args)

这是一种重载写法,如果不懂重载,就要去补一下基础了,这里不再科普

T1,T2,T3在这里出现是因为项目中有些时候可能在我执行这个Handler回调时,想接收一些参数,这样就用到了。

 

无参用法:

TimerManager.instance.doOnce(3000,method);  3000毫秒后执行method

有参用法,比如有两个参数

TimerManager.instance.doOnce<GameObject,Transform>(3000,method,go,tf);  

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 PureSingleton<T> where 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>(T1 param1);
  8 public delegate void Handler<T1, T2>(T1 param1, T2 param2);
  9 public delegate void Handler<T1, T2, T3>(T1 param1, T2 param2, T3 param3);
 10 
 11 public interface IAnimatable {
 12     void AdvanceTime();
 13 }
 14 
 15 /**时钟管理器[同一函数多次计时,默认会被后者覆盖,delay小于1会立即执行]*/
 16 public class TimerManager:PureSingleton<TimerManager>, IAnimatable {
 17 
 18     public static List<IAnimatable> timerList = new List<IAnimatable>();
 19 
 20     public TimerManager() {
 21         timerList.Add(this);
 22     }
 23 
 24     private List<TimerHandler> _pool = new List<TimerHandler>();
 25     /** 用数组保证按放入顺序执行*/
 26     private List<TimerHandler> _handlers = new List<TimerHandler>();
 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     /// /// <summary>
 79     /// 定时执行一次(基于毫秒)
 80     /// </summary>
 81     /// <param name="delay">延迟时间(单位毫秒)</param>
 82     /// <param name="method">结束时的回调方法</param>
 83     /// <param name="args">回调参数</param>
 84     public void doOnce(int delay, Handler method) {
 85         create(false, false, delay, method);
 86     }
 87     public void doOnce<T1>(int delay, Handler<T1> method, params object[] args) {
 88         create(false, false, delay, method, args);
 89     }
 90     public void doOnce<T1, T2>(int delay, Handler<T1, T2> method, params object[] args) {
 91         create(false, false, delay, method, args);
 92     }
 93     public void doOnce<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args) {
 94         create(false, false, delay, method, args);
 95     }
 96 
 97     /// /// <summary>
 98     /// 定时重复执行(基于毫秒)
 99     /// </summary>
100     /// <param name="delay">延迟时间(单位毫秒)</param>
101     /// <param name="method">结束时的回调方法</param>
102     /// <param name="args">回调参数</param>
103     public void doLoop(int delay, Handler method) {
104         create(false, true, delay, method);
105     }
106     public void doLoop<T1>(int delay, Handler<T1> method, params object[] args) {
107         create(false, true, delay, method, args);
108     }
109     public void doLoop<T1, T2>(int delay, Handler<T1, T2> method, params object[] args) {
110         create(false, true, delay, method, args);
111     }
112     public void doLoop<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args) {
113         create(false, true, delay, method, args);
114     }
115 
116     
117     /// <summary>
118     /// 定时执行一次(基于帧率)
119     /// </summary>
120     /// <param name="delay">延迟时间(单位为帧)</param>
121     /// <param name="method">结束时的回调方法</param>
122     /// <param name="args">回调参数</param>
123     public void doFrameOnce(int delay, Handler method) {
124         create(true, false, delay, method);
125     }
126     public void doFrameOnce<T1>(int delay, Handler<T1> method, params object[] args) {
127         create(true, false, delay, method, args);
128     }
129     public void doFrameOnce<T1, T2>(int delay, Handler<T1, T2> method, params object[] args) {
130         create(true, false, delay, method, args);
131     }
132     public void doFrameOnce<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args) {
133         create(true, false, delay, method, args);
134     }
135 
136     /// <summary>
137     /// 定时重复执行(基于帧率)
138     /// </summary>
139     /// <param name="delay">延迟时间(单位为帧)</param>
140     /// <param name="method">结束时的回调方法</param>
141     /// <param name="args">回调参数</param>
142     public void doFrameLoop(int delay, Handler method) {
143         create(true, true, delay, method);
144     }
145     public void doFrameLoop<T1>(int delay, Handler<T1> method, params object[] args) {
146         create(true, true, delay, method, args);
147     }
148     public void doFrameLoop<T1, T2>(int delay, Handler<T1, T2> method, params object[] args) {
149         create(true, true, delay, method, args);
150     }
151     public void doFrameLoop<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args) {
152         create(true, true, delay, method, args);
153     }
154 
155     /// <summary>
156     /// 清理定时器
157     /// </summary>
158     /// <param name="method">method为回调函数本身</param>
159     public void clearTimer(Handler method) {
160         clear(method);
161     }
162     public void clearTimer<T1>(Handler<T1> method) {
163         clear(method);
164     }
165     public void clearTimer<T1, T2>(Handler<T1, T2> method) {
166         clear(method);
167     }
168     public void clearTimer<T1, T2, T3>(Handler<T1, T2, T3> 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     /// <summary>
182     /// 清理所有定时器
183     /// </summary>
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     /// <summary>
197     /// 游戏自启动运行时间,毫秒
198     /// </summary>
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 }

 

大家如果觉得好,多给我回复一下,刷刷人气  ^_^

转载于:https://www.cnblogs.com/Qi-Henry/p/5242852.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值