计时器
1.TimerBase类
using Sirenix.OdinInspector;//odin插件,没有就删除
public abstract class TimerBase
{
[ShowInInspector,LabelText("剩余执行时间")]
internal float countTime;
[ShowInInspector, LabelText("当前执行次数")]
internal int runLoopTimes;
[ShowInInspector, LabelText("最大执行次数")]
internal int maxLoopTimes;
internal float delayTime;
internal bool isFinish;
public abstract void TimeUpdate(float time);
/// <summary>
/// 计时器停止
/// </summary>
public void Stop() => isFinish = true;
/// <summary>
/// 计时器初始化
/// </summary>
protected void Init(float delay, int loop)
{
delayTime = delay;
countTime = delay;
maxLoopTimes = loop;
runLoopTimes = 0;
isFinish = false;
}
/// <summary>
/// 计时器内部计时
/// </summary>
protected bool TimeUpdateBase(float time)
{
countTime -= time;
//循环不是无限并且大于最大循环次数则停止
if (maxLoopTimes != -1 && runLoopTimes >= maxLoopTimes) Stop();
//如果计时器结束或者计时还大于0则返回
if (isFinish || countTime > 0) return false;
countTime = delayTime;
if (maxLoopTimes != -1) runLoopTimes++;
return true;
}
}
2.Timer类
/// <summary>
/// 通用计时器
/// </summary>
public class Timer : TimerBase
{
//无参委托
private Action timeAction;
public void Start(Action action, float delay, int loop)
{
timeAction = action;
Init(delay, loop);
}
/// <summary>
/// 计时器内部计时
/// </summary>
public override void TimeUpdate(float time)
{
if (TimeUpdateBase(time))
{
timeAction?.Invoke();
}
}
}
其他衍生的计时器:配合对象池使用
/// <summary>
/// 对象池回收计时器
/// </summary>
public class TimerRecycle : TimerBase
{
//参数为[TimerRecycle]的委托
private Action<TimerRecycle> timerParAction;
//存储的其他数据
/*--------------对象池相关--------------*/
public GameObject gameObject { get; private set; }
public GameObjectPool objectPool { get; private set; }
public void Start(Action<TimerRecycle> action, float delay, GameObjectPool objectPool, GameObject gameObject)
{
timerParAction = action;
Init(delay, 1);
this.objectPool = objectPool;
this.gameObject = gameObject;
}
public override void TimeUpdate(float time)
{
if (TimeUpdateBase(time))
{
timerParAction?.Invoke(this);
}
}
}
3.TimerManager类
using System.Collections.Generic;
using UnityEngine;
using System;
public class TimerManager : MonoBehaviour
{
/// <summary>
/// 存储正在运行的计时器的列表
/// </summary>
public static List<Timer> timerList = new List<Timer>();
public static List<TimerRecycle> timerRecycleList = new List<TimerRecycle>();
/// <summary>
/// 存储未运行的计时器的队列
/// </summary>
public static Queue<Timer> timerWaitQueue = new Queue<Timer>();
public static Queue<TimerRecycle> timerRecycleWaitQueue = new Queue<TimerRecycle>();
/// <summary>
/// 计时器进行更新
/// </summary>
private void Update()
{
ToUpdate(timerList, timerWaitQueue);
ToUpdate(timerRecycleList, timerRecycleWaitQueue);
}
/// <summary>
/// 通用计时器,loop为-1时为一直循环
/// </summary>
public static Timer AddTimer(Action action, float delay, int loop)
{
Timer timer = timerWaitQueue.Count > 0 ? timerWaitQueue.Dequeue() : new Timer();
timer.Start(action, delay, loop);
timerList.Add(timer);
return timer;
}
/// <summary>
/// 回收计时器
/// </summary>
public static TimerRecycle AddTimer(Action<TimerRecycle> action, float delay, GameObjectPool gameObjectPool, GameObject gameObject)
{
TimerRecycle timer = timerRecycleWaitQueue.Count > 0 ? timerRecycleWaitQueue.Dequeue() : new TimerRecycle();
timer.Start(action, delay, gameObjectPool, gameObject);
timerRecycleList.Add(timer);
return timer;
}
/// <summary>
/// 计时器更新语句
/// </summary>
public void ToUpdate<T>(List<T> timerList,Queue<T> timerWaitQueue) where T:TimerBase
{
for (int i = 0; i < timerList.Count; i++)
{
if (timerList[i].isFinish)
{
timerWaitQueue.Enqueue(timerList[i]);
timerList.RemoveAt(i);
i--;
}
else timerList[i].TimeUpdate(Time.deltaTime);
}
}
}