今天参考着我们项目里面的egret传奇的定时器,写了一个unity的定时器工具类:
测试了一下,没发现问题,就直接分享一下:
了解了可省略参数写法:(以前还不知道QAQ)
params object[] arge
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public struct timerData {
public Delegate method;
public float delay;
public int repeatNum;
public object[] arge; //参数
public int index;
public float exeTime;
}
public class TimeEvent : MonoBehaviour
{
private static TimeEvent instance;
/// <summary>
/// 单例
/// </summary>
public static TimeEvent Instance
{
get
{
if (!instance)
{
instance = GameObject.FindObjectOfType<TimeEvent>();
}
if (!instance)
{
GameObject obj = new GameObject(typeof(TimeEvent).ToString());
instance = obj.AddComponent<TimeEvent>();
}
return instance;
}
}
public Dictionary<string, timerData> map;
private void Awake()
{
map = new Dictionary<string, timerData>();
StartCoroutine(tiemr());
}
/**
* 注册一个计时器
*/
private void onTime(string eventname, Delegate method, float delay, int repeatNum, bool runNow,bool cover, params object[] arge)
{
if (has(eventname) && cover == false)
{
Debug.LogError(eventname+"已经注册过了,禁止重复注册");
}
timerData data = new timerData();
data.method = method;
data.delay = delay;
data.repeatNum = repeatNum == 0 ? 1 : repeatNum;
data.index = repeatNum < 0 ? -1 : 0;
data.exeTime = Time.time;
data.arge = arge;
if (runNow)
{
method.DynamicInvoke(arge);
data.index = 1;
}
if (cover && has(eventname))
{
this.map[eventname] = data;
}
else
{
this.map.Add(eventname, data);
}
}/// <summary>
/// 无参的计时器注册
/// </summary>
/// <param name="eventname">注册计时器名字</param>
/// <param name="method">定时器回调函数。</param>
/// <param name="delay">执行间隔(秒为单位)</param>
/// <param name="repeatNum">执行次数,-1为无限循环</param>
/// <param name="runNow">是否立即回调一次,默认否</param>
/// <param name="cover">如果当前handler已存在,是否覆盖当前结果</param>
/// <param name="arge">回调参数,传入数组</param>
public void onTimer(string eventname, Action method, float delay, int repeatNum, bool runNow, bool cover, params object[] arge)
{
this.onTime(eventname, method, delay, repeatNum, runNow, cover, arge);
}
/// <summary>
/// 一个参数的计时器
/// </summary>
/// <typeparam name="T">参数</typeparam>
public void onTimer<T>(string eventname, Action<T> method, float delay, int repeatNum, bool runNow, bool cover, params object[] arge)
{
this.onTime(eventname, method, delay, repeatNum, runNow, cover, arge);
}
/// <summary>
/// 两个参数的计时器
/// </summary>
/// <typeparam name="T">参数1</typeparam>
/// <typeparam name="T1">参数2</typeparam>
public void onTimer<T,T1>(string eventname, Action<T, T1> method, float delay, int repeatNum, bool runNow, bool cover, params object[] arge)
{
this.onTime(eventname, method, delay, repeatNum, runNow, cover, arge);
}
/// <summary>
/// 三个参数的计时器
/// </summary>
/// <typeparam name="T">参数1</typeparam>
/// <typeparam name="T1">参数2</typeparam>
/// <typeparam name="T2">参数3</typeparam>
public void onTimer<T,T1,T2>(string eventname, Action<T, T1, T2> method, float delay, int repeatNum, bool runNow, bool cover, params object[] arge)
{
this.onTime(eventname, method, delay, repeatNum, runNow, cover, arge);
}
/// <summary>
/// 移除注册函数
/// </summary>
/// <param name="eventname"></param>
public void offTimer(string eventname)
{
map.Remove(eventname);
}
/// <summary>
/// 检测是否已经注册过了
/// </summary>
/// <param name="eventname"></param>
/// <returns></returns>
public bool has(string eventname)
{
return map.ContainsKey(eventname);
}
public IEnumerator tiemr()
{
if(map.Count>0)
{
for(int i=0;i<map.Count;i++)
{
var item = map.ElementAt(i);
timerData data = item.Value;
if (data.exeTime + data.delay <= Time.time)
{
data.exeTime = Time.time;
data.method.DynamicInvoke(data.arge);
if (!map.ContainsKey(item.Key)) continue;
map[item.Key] = data;
if (item.Value.repeatNum != -1)
{
data.index++;
map[item.Key] = data;
if (data.index >= data.repeatNum)
{
this.offTimer(item.Key);
}
}
}
}
}
yield return null;
StartCoroutine(tiemr());
}
}
调用:
void Start()
{
TimeEvent.Instance.onTimer<int, string>("TestTime", settime, 4, -1, false, false, 12, "this");
}
public void settime(int a, string b)
{
Debug.Log(Time.time + "---" + a + "---" + b);
}
输出结果: