网页链接:https://devpress.csdn.net/guangzhou/649ed8f88501cb0bc4b12899.html
1. 不使用定时任务系统的定时器实现
1.1 Time.deltaTime
using UnityEngine;
public class Test : MonoBehaviour
{
public float timer = 0f;
void Update()
{
timer += Time.deltaTime;
if (timer >= 2)
{
doSomething();
timer = 0f; // 定时2秒
}
}
void doSomething()
{
Debug.Log("每2秒执行一次");
}
}
1.2 Time.time
using UnityEngine;
public class Test : MonoBehaviour
{
public float timer = 0f;
void Start()
{
timer = Time.time;
}
void Update()
{
timer += Time.deltaTime;
if (Time.time - timer >= 2)// 定时2秒
{
doSomething();
timer = Time.time;
}
}
void doSomething()
{
Debug.Log("每2秒执行一次");
}
}
1.3 使用延迟调用函数
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
//0秒后,每2秒执行一次doSomething
InvokeRepeating("doSomething", 0, 2);
}
void doSomething()
{
Debug.Log("每2秒执行一次");
}
}
1.4 使用协程
using System;
using System.Collections;
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
//每2秒执行一次doSomething
StartCoroutine(UpdateTimer(2f, doSomething));
}
void doSomething()
{
Debug.Log("每2秒执行一次");
}
IEnumerator UpdateTimer(float timer,Action callBack)
{
var wait = new WaitForSeconds(timer);
while (true)
{
yield return wait;
callBack();
}
}
}
2. 简易定时任务
定时任务类:
/*
* FileName: PETimeTask
* Author: ming
* CreateTime: 2023/6/29 18:27:54
* Description: 定时任务
*
*/
using System;
public class PETimeTask
{
public int tid;
public Action callBack; // 要执行什么任务
public float destTime; // 多少时间后执行任务 单位为毫秒
public float count; // 执行任务的次数
public float delay; // 延迟的时间
public PETimeTask(int tid, Action callBack, float destTime, float delay, float count)
{
this.tid = tid;
this.callBack = callBack;
this.destTime = destTime;
this.count = count;
this.delay = delay;
}
}
public enum PETimeUnit
{
Millise,
Second,
Minute,
Hour,
Day
}
简易定时任务系统:
/*
* FileName: TimerSystemSimple
* Author: ming
* CreateTime: 2023/6/29 18:26:36
* Description: 简易定时任务系统
*
*/
using System;
using UnityEngine;
using System.Collections.Generic;
public class TimerSystemSimple : MonoBehaviour
{
private int tid = 0; // 全局任务 id
public static TimerSystemSimple _instance;
// 任务列表
private List<PETimeTask> mTimerTaskList = new List<PETimeTask>();
void Awake()
{
_instance = this;
}
private void Update()
{
for (int i = 0; i < mTimerTaskList.Count; i++)
{
PETimeTask timeTask = mTimerTaskList[i];
// 任务已经到达执行时间
if (timeTask.destTime <= Time.realtimeSinceStartup * 1000)
{
if (timeTask.callBack != null) timeTask.callBack();
// 移除已经完成的任务
if (timeTask.count == 1)
{
mTimerTaskList.RemoveAt(i);
i--;
}
else
{
if (timeTask.count != 0)
{
timeTask.count -= 1;
}
timeTask.destTime += timeTask.delay;
}
}
}
}
/*
* callback: 回调
* delay: 延迟执行时间
* count: 执行次数,0--循环执行
* PETimeUnit: 时间单位,默认为秒
* return: 返回任务唯一id
*/
public int AddTimeTask(Action callback, float delay, int count = 1, PETimeUnit timeUnit = PETimeUnit.Second) {
// 转换时间格式
if (timeUnit != PETimeUnit.Millise)
{
switch (timeUnit)
{
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.LogWarning("Time Task Type Is Error...");
break;
}
}
tid++;
float destTime = Time.realtimeSinceStartup * 1000 + delay;
mTimerTaskList.Add(new PETimeTask(tid, callback, destTime, delay, count));
return tid;
}
/*
* tid: 任务唯一id
* return: 移除成功返回true,不存在返回false
*/
public bool RemoveTimeTask(int tid)
{
bool exist = false;
for (int i = 0; i < mTimerTaskList.Count; i++) {
if (tid == mTimerTaskList[i].tid)
{
mTimerTaskList.RemoveAt(i);
exist = true;
}
}
return exist;
}
public bool ReplaceTimeTask(int tid, Action callback, float delay, int count = 1, PETimeUnit timeUnit = PETimeUnit.Second)
{
// 转换时间格式
if (timeUnit != PETimeUnit.Millise)
{
switch (timeUnit)
{
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.LogWarning("Time Task Type Is Error...");
break;
}
}
bool isReplace = false;
for (int i = 0; i < mTimerTaskList.Count; i++)
{
if(tid == mTimerTaskList[i].tid)
{
// 生成新的定时任务
float destTime = Time.realtimeSinceStartup * 1000 + delay;
PETimeTask newTask = new PETimeTask(tid, callback, destTime, delay, count);
mTimerTaskList[i] = newTask;
isReplace = true;
break;
}
}
return isReplace;
}
}
3. 更为完善的定时任务系统
/*
* FileName: TimerSystem
* Author: ming
* CreateTime: 2023/6/29 18:26:36
* Description: 定时任务系统
*
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class TimerSystem : MonoBehaviour
{
private int tid; // 全局ID
private static readonly string obj = "lock";
public static TimerSystem _instance;
private List<PETimeTask> mTimerTaskList = new List<PETimeTask>();
// 临时缓存列表
private List<PETimeTask> mTempTimeTaskList = new List<PETimeTask>();
// 存储tid
private List<int> tidList = new List<int>();
// 存储需清理的ID
private List<int> recIDList = new List<int>();
private void Awake()
{
_instance = this;
}
// 实现基础定时任务
private void Update()
{
// 加入缓存区中的定时任务
for (int tempIndex = 0; tempIndex < mTempTimeTaskList.Count; tempIndex++)
{
mTimerTaskList.Add(mTempTimeTaskList[tempIndex]);
}
mTempTimeTaskList.Clear();
// 遍历检测任务是否达到条件
for (int i = 0; i < mTimerTaskList.Count; i++)
{
PETimeTask timeTask = mTimerTaskList[i];
// 任务时间超过当前时间
if (timeTask.destTime > Time.realtimeSinceStartup * 1000)
{
continue;
}
else
{
Action action = timeTask.callBack;
if (action != null)
{
action();
}
//移除已经完成的任务
if (timeTask.count == 1)
{
mTimerTaskList.RemoveAt(i);
i--;
recIDList.Add(timeTask.tid);
}
else
{
if (timeTask.count != 0)
{
timeTask.count -= 1;
}
timeTask.destTime += timeTask.delay;
}
}
}
// 当需清理的ID缓存区有东西时,进行清理
if (recIDList.Count > 0)
{
RecycleTid();
}
}
private void RecycleTid()
{
for (int i = 0; i < recIDList.Count; i++)
{
int tid = recIDList[i];
for (int j = 0; j < tidList.Count; j++)
{
if (tid == tidList[j])
{
tidList.RemoveAt(j);
break;
}
}
}
recIDList.Clear();
}
// 添加计时器任务
public int AddTimeTask(Action callBack, float delay, int count = 1, PETimeUnit timeUnit = PETimeUnit.Millise)
{
if (timeUnit != PETimeUnit.Millise)
{
switch (timeUnit)
{
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.LogWarning("Time Task Type Is Error...");
break;
}
}
int tid = GetId();
float destTime = Time.realtimeSinceStartup * 1000 + delay;
mTempTimeTaskList.Add(new PETimeTask(tid, callBack, destTime, delay, count));
tidList.Add(tid);
return tid;
}
public bool DelectTimeTask(int tid)
{
bool exist = false;
for (int i = 0; i < mTimerTaskList.Count; i++)
{
if (tid == mTimerTaskList[i].tid)
{
mTimerTaskList.RemoveAt(i);
for (int j = 0; j < tidList.Count; j++)
{
if (tid == tidList[j])
{
tidList.RemoveAt(j);
break;
}
}
exist = true;
break;
}
}
if (!exist)
{
for (int i = 0; i < mTempTimeTaskList.Count; i++)
{
if (tid == mTempTimeTaskList[i].tid)
{
mTempTimeTaskList.RemoveAt(i);
for (int j = 0; j < tidList.Count; j++)
{
if (tid == tidList[j])
{
tidList.RemoveAt(j);
break;
}
}
exist = true;
break;
}
}
}
return exist;
}
public bool ReplaceTimeTask(int tid, Action callBack, float delay, int count = 1, PETimeUnit timeUnit = PETimeUnit.Millise)
{
if (timeUnit != PETimeUnit.Millise)
{
switch (timeUnit)
{
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.LogWarning("Time Task Type Is Error...");
break;
}
}
bool isReplace = false;
float destTime = Time.realtimeSinceStartup * 1000 + delay;
PETimeTask newTask = new PETimeTask(tid, callBack, destTime, delay, count);
for (int i = 0; i < mTimerTaskList.Count; i++)
{
if (mTimerTaskList[i].tid == tid)
{
mTimerTaskList[i] = newTask;
isReplace = true;
break;
}
}
if (!isReplace)
{
for (int i = 0; i < mTempTimeTaskList.Count; i++)
{
if (mTempTimeTaskList[i].tid == tid)
{
mTempTimeTaskList[i] = newTask;
isReplace = true;
break;
}
}
}
return isReplace;
}
public int GetId