这是一个单例类,适合整个项目的时间管理,从此让我们摆脱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()
{
private static T _instance;
public static T instance
{
get
{
if (_instance == null)
{
_instance = new T();
}
return _instance;
}
}
}
2.正类 TimerManager
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public delegate void Handler();
public delegate void Handler<T1>(T1 param1);
public delegate void Handler<T1, T2>(T1 param1, T2 param2);
public delegate void Handler<T1, T2, T3>(T1 param1, T2 param2, T3 param3);
public interface IAnimatable
{
void AdvanceTime();
}
/**
* 需要在一个长期存在的Update里面初始化
* foreach (IAnimatable animatable in TimerManager.timerList)
{
animatable.AdvanceTime();
}
*/
/**时钟管理器[同一函数多次计时,默认会被后者覆盖,delay小于1会立即执行]*/
public class TimerManager : PureSingleton<TimerManager>, IAnimatable
{
public static List<IAnimatable> timerList = new List<IAnimatable>();
public TimerManager()
{
timerList.Add(this);
}
private List<TimerHandler> _pool = new List<TimerHandler>();
/** 用数组保证按放入顺序执行*/
private List<TimerHandler> _handlers = new List<TimerHandler>();
private int _currFrame = 0;
private uint _index = 0;
public void AdvanceTime()
{
_currFrame++;
for (int i = 0; i < _handlers.Count; i++)
{
TimerHandler handler = _handlers[i];
long t = handler.userFrame ? _currFrame : currentTime;
if (t >= handler.exeTime)
{
Delegate method = handler.method;
object[] args = handler.args;
if (handler.repeat)
{
while (t >= handler.exeTime)
{
handler.exeTime += handler.delay;
method.DynamicInvoke(args);
}
}
else
{
clear(handler.method);
method.DynamicInvoke(args);
}
}
}
}
private object create(bool useFrame, bool repeat, int delay, Delegate method, params object[] args)
{
if (method == null)
{
return null;
}
//如果执行时间小于1,直接执行
if (delay < 1)
{
method.DynamicInvoke(args);
return -1;
}
TimerHandler handler;
if (_pool.Count > 0)
{
handler = _pool[_pool.Count - 1];
_pool.Remove(handler);
}
else
{
handler = new TimerHandler();
}
handler.userFrame = useFrame;
handler.repeat = repeat;
handler.delay = delay;
handler.method = method;
handler.args = args;
handler.exeTime = delay + (useFrame ? _currFrame : currentTime);
_handlers.Add(handler);
return method;
}
/// /// <summary>
/// 定时执行一次(基于毫秒)
/// </summary>
/// <param name="delay">延迟时间(单位毫秒)</param>
/// <param name="method">结束时的回调方法</param>
/// <param name="args">回调参数</param>
public void doOnce(int delay, Handler method)
{
create(false, false, delay, method);
}
public void doOnce<T1>(int delay, Handler<T1> method, params object[] args)
{
create(false, false, delay, method, args);
}
public void doOnce<T1, T2>(int delay, Handler<T1, T2> method, params object[] args)
{
create(false, false, delay, method, args);
}
public void doOnce<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args)
{
create(false, false, delay, method, args);
}
/// /// <summary>
/// 定时重复执行(基于毫秒)
/// </summary>
/// <param name="delay">延迟时间(单位毫秒)</param>
/// <param name="method">结束时的回调方法</param>
/// <param name="args">回调参数</param>
public void doLoop(int delay, Handler method)
{
create(false, true, delay, method);
}
public void doLoop<T1>(int delay, Handler<T1> method, params object[] args)
{
create(false, true, delay, method, args);
}
public void doLoop<T1, T2>(int delay, Handler<T1, T2> method, params object[] args)
{
create(false, true, delay, method, args);
}
public void doLoop<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args)
{
create(false, true, delay, method, args);
}
/// <summary>
/// 定时执行一次(基于帧率)
/// </summary>
/// <param name="delay">延迟时间(单位为帧)</param>
/// <param name="method">结束时的回调方法</param>
/// <param name="args">回调参数</param>
public void doFrameOnce(int delay, Handler method)
{
create(true, false, delay, method);
}
public void doFrameOnce<T1>(int delay, Handler<T1> method, params object[] args)
{
create(true, false, delay, method, args);
}
public void doFrameOnce<T1, T2>(int delay, Handler<T1, T2> method, params object[] args)
{
create(true, false, delay, method, args);
}
public void doFrameOnce<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args)
{
create(true, false, delay, method, args);
}
/// <summary>
/// 定时重复执行(基于帧率)
/// </summary>
/// <param name="delay">延迟时间(单位为帧)</param>
/// <param name="method">结束时的回调方法</param>
/// <param name="args">回调参数</param>
public void doFrameLoop(int delay, Handler method)
{
create(true, true, delay, method);
}
public void doFrameLoop<T1>(int delay, Handler<T1> method, params object[] args)
{
create(true, true, delay, method, args);
}
public void doFrameLoop<T1, T2>(int delay, Handler<T1, T2> method, params object[] args)
{
create(true, true, delay, method, args);
}
public void doFrameLoop<T1, T2, T3>(int delay, Handler<T1, T2, T3> method, params object[] args)
{
create(true, true, delay, method, args);
}
/// <summary>
/// 清理定时器
/// </summary>
/// <param name="method">method为回调函数本身</param>
public void clearTimer(Handler method)
{
clear(method);
}
public void clearTimer<T1>(Handler<T1> method)
{
clear(method);
}
public void clearTimer<T1, T2>(Handler<T1, T2> method)
{
clear(method);
}
public void clearTimer<T1, T2, T3>(Handler<T1, T2, T3> method)
{
clear(method);
}
private void clear(Delegate method)
{
TimerHandler handler = _handlers.FirstOrDefault(t => t.method == method);
if (handler != null)
{
_handlers.Remove(handler);
handler.clear();
_pool.Add(handler);
}
}
/// <summary>
/// 清理所有定时器
/// </summary>
public void clearAllTimer()
{
foreach (TimerHandler handler in _handlers)
{
clear(handler.method);
clearAllTimer();
return;
}
}
public static void RemoveTimerMgr(TimerManager timerMgr)
{
timerList.Remove(timerMgr);
}
/// <summary>
/// 游戏自启动运行时间,毫秒
/// </summary>
public long currentTime
{
get { return (long)(Time.time * 1000); }
}
/**定时处理器*/
private class TimerHandler
{
/**执行间隔*/
public int delay;
/**是否重复执行*/
public bool repeat;
/**是否用帧率*/
public bool userFrame;
/**执行时间*/
public long exeTime;
/**处理方法*/
public Delegate method;
/**参数*/
public object[] args;
/**清理*/
public void clear()
{
method = null;
args = null;
}
}
}
转载于:https://blog.csdn.net/adf26645/article/details/102085215