基于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);
}

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

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值