基于unity的计时器(协程)

今天参考着我们项目里面的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);
}

输出结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/QO_GQ/article/details/117927407
今日推荐