Unity 定时器和帧定时脚本工具

Unity 定时器脚本工具

using System;
using System.Collections.Generic;
using UnityEngine;

//开发目标:
//支持时间定时,帧定时
//定时任务可循环,可取消,可替换
//使用简单,调用方便

public class TimerSys : MonoBehaviour
{
public static TimerSys Instance;
private static readonly string obj = “lock”;
private int tid;
private List tidLst = new List(); //保存住所有任务的tid
private List recTidLst = new List(); //清除 tid

private List<PETimeTask> tempTimeLst = new List<PETimeTask>();  //缓存
private List<PETimeTask> taskTimeLst = new List<PETimeTask>();

/// <summary>
/// 下面是帧定时
/// </summary>
private int frameCounter;
private List<PEFrameTask> tempFrameLst = new List<PEFrameTask>();  //缓存
private List<PEFrameTask> taskFrameLst = new List<PEFrameTask>();

// Use this for initialization
public void Init()
{
    Instance = this;
    Debug.Log("TimeSys Init Done");
}

private void Update()
{
    CheckTimeTask();
    CheckFrameTask();

    if (recTidLst.Count > 0)
    {
        RecycleTid();

    }
}


private void CheckTimeTask()
{
    //加入缓存区中的定时任务
    for (int tmpIndex = 0; tmpIndex < tempTimeLst.Count; tmpIndex++)
    {
        taskTimeLst.Add(tempTimeLst[tmpIndex]);
    }
    tempTimeLst.Clear();
    //遍历检测任务是否到达条件 TODO
    for (int index = 0; index < taskTimeLst.Count; index++)
    {
        PETimeTask task = taskTimeLst[index];
        if (Time.realtimeSinceStartup * 1000 < task.destTime)
        {
            continue;
        }
        else
        {
            Action cb = task.callback;
            try
            {
                if (cb != null)
                {
                    cb();
                }

            }
            catch (Exception e)
            {
                Debug.Log(e.ToString());
            }

            //移除已经完成的任务
            if (task.count == 1)
            {
                taskTimeLst.RemoveAt(index);
                index--;
                recTidLst.Add(task.tid);

            }
            else
            {
                if (task.count != 0)
                {
                    task.count -= 1;
                }
                task.destTime += task.delay;
            }
        }
    }
}

private void CheckFrameTask()
{
    //加入缓存区中的定时任务
    for (int tmpIndex = 0; tmpIndex < tempFrameLst.Count; tmpIndex++)
    {
        taskFrameLst.Add(tempFrameLst[tmpIndex]);
    }
    tempFrameLst.Clear();

    frameCounter += 1;
    //遍历检测任务是否到达条件 TODO
    for (int index = 0; index < taskFrameLst.Count; index++)
    {
        PEFrameTask task = taskFrameLst[index];
        if (frameCounter < task.destFrame)
        {
            continue;
        }
        else
        {
            Action cb = task.callback;
            try
            {
                if (cb != null)
                {
                    cb();
                }

            }
            catch (Exception e)
            {
                Debug.Log(e.ToString());
            }

            //移除已经完成的任务
            if (task.count == 1)
            {
                taskFrameLst.RemoveAt(index);
                index--;
                recTidLst.Add(task.tid);

            }
            else
            {
                if (task.count != 0)
                {
                    task.count -= 1;
                }
                task.destFrame += task.delay;
            }
        }
    }
}
#region  TimeTask
/// <summary>
/// 添加
/// </summary>
/// <param name="callback"></param>
/// <param name="delay"></param>
/// <param name="timeUniy"></param>
/// <param name="count"></param>
/// <returns></returns>
public int AddTimeTask(Action callback, float delay, PETimeUnit timeUniy = PETimeUnit.Millisecond,int count=1)
{
    if (timeUniy != PETimeUnit.Millisecond)
    {
        switch (timeUniy)
        {
            case PETimeUnit.Second:
                delay = delay * 1000;
                break;
            case PETimeUnit.Minute:
                delay = delay * 1000 * 60;
                break;
            case PETimeUnit.Hour:
                delay = delay * 1000 * 60 * 60;
                break;
            case PETimeUnit.Day:
                delay = delay * 1000 * 60 * 60 * 24;
                break;
            default:
                Debug.Log("Add Task TimeUnity Type Error...");
                break;
        }
    }

    int tid=GetTid();

    float destTime = Time.realtimeSinceStartup * 1000 + delay;
    tempTimeLst.Add(new PETimeTask(tid,callback, destTime, delay, count));

    tidLst.Add(tid);

   return tid;
}
 /// <summary>
 /// 删除
 /// </summary>
 /// <param name="tid"></param>
 /// <returns></returns>

public bool DelelteTimeTask(int tid)
{
bool exist = false;

    for (int i = 0; i < taskTimeLst.Count; i++)
    {
        PETimeTask task = taskTimeLst[i];
        if (task.tid == tid)
        {
            taskTimeLst.RemoveAt(i);
            for (int j = 0; j < tidLst.Count; j++)
            {
                if (tidLst[j] == tid)
                {
                    tidLst.RemoveAt(i);
                    break;
                }
            }

            exist = true;
            break;
        }
    }

    if (!exist)
    {
        for (int i = 0; i < tempTimeLst.Count; i++)
        {
            PETimeTask task = tempTimeLst[i];
            if (task.tid == tid)
            {
                tempTimeLst.RemoveAt(i);
                for (int j = 0; j < tidLst.Count; j++)
                {
                    if (tidLst[j] == tid)
                    {
                        tidLst.RemoveAt(i);
                        break;
                    }
                }
                exist = true;
                break;
            }
        }
    }
    return exist;
}
/// <summary>
/// 替换
/// </summary>
/// <param name="tid"></param>
/// <param name="callback"></param>
/// <param name="delay"></param>
/// <param name="timeUniy"></param>
/// <param name="count"></param>
/// <returns></returns>
public bool ReplaceTimeTask(int tid, Action callback, float delay, PETimeUnit timeUniy = PETimeUnit.Millisecond, int count = 1)
{
    if (timeUniy != PETimeUnit.Millisecond)
    {
        switch (timeUniy)
        {
            case PETimeUnit.Second:
                delay = delay * 1000;
                break;
            case PETimeUnit.Minute:
                delay = delay * 1000 * 60;
                break;
            case PETimeUnit.Hour:
                delay = delay * 1000 * 60 * 60;
                break;
            case PETimeUnit.Day:
                delay = delay * 1000 * 60 * 60 * 24;
                break;
            default:
                Debug.Log("Add Task TimeUnity Type Error...");
                break;
        }
    }

    float destTime = Time.realtimeSinceStartup * 1000 + delay;
    PETimeTask newTask = new PETimeTask(tid, callback, destTime, delay, count);

    bool isRep = false;
    for (int i = 0; i < taskTimeLst.Count; i++)
    {
        if (taskTimeLst[i].tid == tid)
        {
            taskTimeLst[i] = newTask;
            isRep = true;
            break;
        }
    }

    if (!isRep)
    {
        for (int i = 0; i < tempTimeLst.Count; i++)
        {
            if (tempTimeLst[i].tid == tid)
            {
                tempTimeLst[i] = newTask;
                isRep = true;
                break;
            }
        }
    }
    return isRep;
}
#endregion

#region FrameTask
///
/// 添加
///
///
///
///
///
///
public int AddFrameTask(Action callback, int delay, int count = 1)
{

    int tid = GetTid();

    
    tempFrameLst.Add(new PEFrameTask(tid, callback, frameCounter+delay, delay, count));

    tidLst.Add(tid);

    return tid;

}
/// <summary>
/// 删除
/// </summary>
/// <param name="tid"></param>
/// <returns></returns>
public bool DelelteFrameTask(int tid)
{
    bool exist = false;

    for (int i = 0; i < taskFrameLst.Count; i++)
    {
        PEFrameTask task = taskFrameLst[i];
        if (task.tid == tid)
        {
            taskFrameLst.RemoveAt(i);
            for (int j = 0; j < tidLst.Count; j++)
            {
                if (tidLst[j] == tid)
                {
                    tidLst.RemoveAt(i);
                    break;
                }
            }

            exist = true;
            break;
        }
    }

    if (!exist)
    {
        for (int i = 0; i < tempFrameLst.Count; i++)
        {
            PEFrameTask task = tempFrameLst[i];
            if (task.tid == tid)
            {
                tempFrameLst.RemoveAt(i);
                for (int j = 0; j < tidLst.Count; j++)
                {
                    if (tidLst[j] == tid)
                    {
                        tidLst.RemoveAt(i);
                        break;
                    }
                }
                exist = true;
                break;
            }
        }
    }
    return exist;
}
/// <summary>
/// 替换
/// </summary>
/// <param name="tid"></param>
/// <param name="callback"></param>
/// <param name="delay"></param>
/// <param name="timeUniy"></param>
/// <param name="count"></param>
/// <returns></returns>
public bool ReplaceFrameTask(int tid, Action callback, int delay, int count = 1)
{
    PEFrameTask newTask = new PEFrameTask(tid, callback, frameCounter+ delay, delay, count);
    bool isRep = false;
    for (int i = 0; i < taskFrameLst.Count; i++)
    {
        if (taskFrameLst[i].tid == tid)
        {
            taskFrameLst[i] = newTask;
            isRep = true;
            break;
        }
    }

    if (!isRep)
    {
        for (int i = 0; i < tempFrameLst.Count; i++)
        {
            if (tempFrameLst[i].tid == tid)
            {
                tempFrameLst[i] = newTask;
                isRep = true;
                break;
            }
        }
    }
    return isRep;
}

#endregion
 #region  Tool Methonds

private int GetTid()
{
    lock (obj)
    {
        tid += 1;
        //安全代码,以防万一
        while (true)
        {
            if (tid == int.MaxValue)
            {
                tid = 0;
            }

            bool used = false;
            for (int i = 0; i < tidLst.Count; i++)
            {
                if (tid == tidLst[i])
                {
                    used = true;
                    break;
                }
            }

            if (!used)
            {
                break;
            }
            else
            {
                tid += 1;
            }
        }

    }
    return tid;
}


private void RecycleTid()
{

    for (int i = 0; i < recTidLst.Count; i++)
    {
        int tid = recTidLst[i];

        for (int j = 0; j < tidLst.Count; j++)
        {
            if (tidLst[j] == tid)
            {
                tidLst.RemoveAt(j);
                break;

            }
        }
    }
    recTidLst.Clear();
}
#endregion

}

public class PETimeTask
{
public int tid;
public Action callback; //执行什么
public float destTime;//目标执行时间
public float delay; //这个是再次加上时间
public int count;//执行次数

public PETimeTask(int tid, Action callback, float destTime, float delay, int count)
{
    this.callback = callback;
    this.destTime = destTime;
    this.delay = delay;
    this.count = count;
    this.tid = tid;
}

}

public class PEFrameTask
{
public int tid;
public Action callback; //执行什么
public int destFrame;//目标执行时间
public int delay; //这个是再次加上时间
public int count;//执行次数

public PEFrameTask(int tid, Action callback, int destFrame, int delay, int count)
{
    this.callback = callback;
    this.destFrame = destFrame;
    this.delay = delay;
    this.count = count;
    this.tid = tid;
}

}

public enum PETimeUnit
{
Millisecond,
Second,
Minute,
Hour,
Day
}

///
在使用的脚本初始化里面加上
TimerSys timer = GetComponent();
timer.Init();
下面是这个脚本里的一些方法
第一个参数:传过来的函数
第二个参数:每隔多少时间执行一次
第三个参数:是个时间枚举
第四个参数:是执行几次,默认参数是1, 写0表示一直执行
返回值:是任务的ID
TimerSys.Instance.AddTimeTask();//添加定时任务

第一个参数:是任务的ID
TimerSys.Instance.DelelteTimeTask();//删除定时任务

第一个参数:是任务的ID
第二个参数:传过来的函数
第三个参数:每隔多少时间执行一次
第四个参数:是个时间枚举
第五个参数:是执行几次,默认参数是1, 写0表示一直执行
TimerSys.Instance.ReplaceTimeTask();//替换定时任务

第一个参数:传过来的函数
第二个参数:每隔多少时间执行一次
第三个参数:是执行几次,默认参数是1, 写0表示一直执行
TimerSys.Instance.AddFrameTask();//添加帧定时任务

第一个参数:是任务的ID
TimerSys.Instance.DelelteFrameTask();//删除帧定时任务

第一个参数:是任务的ID
第二个参数:传过来的函数
第三个参数:每隔多少时间执行一次
第四个参数:是执行几次,默认参数是1, 写0表示一直执行
TimerSys.Instance.ReplaceFrameTask();//替换帧定时任务

感谢Plane老师

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值