在项目开发阶段有很多的计时器需求,包括游戏时间计时,验证码时间计时等。如果没有一个计时器管理类,将会非常混乱,为了更好的管理计时器,封装了一个计时器管理类
TimerMoudle 管理一个计时器,TimerMoudle对外公开的函数及字段如下:
函数 | 解释 |
---|---|
Play(bool restart=false) | 运行计时器(restart表示是否重新开始计时,默认为false继续计时) |
Pause() | 暂停计时器 |
Stop() | 停止计时器 |
Close(bool isDestroy) | 关闭计时器(isDestroy表示是否完全销毁即不入对象池,默认为false) |
OnComplete(Action act) | 计时器计时结束的回调 |
OnProgress(Action |
计时器计时进度(当前时间,总时间) |
TimerMoudle(string _flag,float _maxTimer)构造函数 | _flag计时器标识符,_maxTimer计时器的时间 |
ReInit(string _flag,float _maxTimer) | 计时器重置,在TimerManager中管理 |
字段 | 解释 |
---|---|
flag | 标识符(只读) |
maxTimer | 计时器最大时间(只读) |
curTimer | 计时器当前时间(只读) |
isPlaying | 计时器是否正在运行(只读) |
isLoop | 是否循环计时(读写) |
TimerMoudleExpand TimerMoudle对象的拓展,用于释放计时器
函数 | 解释 |
---|---|
Dispose(this TimerManager.TimerMoudle timerMoudle,bool isDestroy=false) | isDestroy表示是否销毁计时器即不入对象池 |
TimerManager 管理所有的TimerMoudle,对外公开的函数如下:
函数 | 解释 |
---|---|
CreateTimer(string flag,float timer,bool isPlay=true) | 创建计时器(标识符,计时器时间,是否直接运行计时器) |
DisposeTimer(string flag,bool isDestroy=false) | 释放计时器(标识符,是否销毁即不入对象池) |
GetTimer(string flag) | 根据标识符得到计时器 |
注意:TimerMoudle中的Close函数与TimerMoudleExpand中的Dispose函数及TimerManager中的Dispose函数的区别:TimerMoudle中的Close函数表示释放对象中的内存,而TimerMoudleExpand中的Dispose函数及TimerManager中的Dispose函数不仅释放TimerMoudle中的内存,同时也把指向这个对象的引用也给释放了,推荐使用后两种释放方式!!!
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
///
/// 计时器管理类
///
public class TimerManager : MonoBehaviour
{
private static TimerManager _instance;
public static TimerManager instance
{
get
{
if (_instance==null)
{
_instance = GameObject.FindObjectOfType();
if (_instance==null)
{
GameObject OBJ = new GameObject("TimerManager");
_instance = OBJ.AddComponent();
DontDestroyOnLoad(OBJ);
}
}
return _instance;
}
}
///
/// 所有正在使用的计时器字典
///
private Dictionary timerDict = new Dictionary();
///
/// 闲置计时器的池子
///
private static List timerPool = new List();
///
/// 池子最大容量
///
public int poolMaxCount=10;
///
/// Update事件
///
private static event Action OnUpdateEvent;
///
/// 创建一个计时器
///
/// 计时器flag
/// 计时器时间
/// 是否开始计时
///
public TimerMoudle CreateTimer(string flag,float timer,bool isPlay=true)
{
if (GetTimer(flag)!=null)
{
Debug.LogWarning("CreateTimer Error: 创建计时器Flag重复:"+flag);
return null;
}
TimerMoudle timerMoudle = null;
if (timerPool.Count>0)
{
timerMoudle = timerPool[0];
timerPool.RemoveAt(0);
timerMoudle.ReInit(flag, timer);
}
else
{
timerMoudle= new TimerMoudle(flag,timer);
}
if (isPlay&&timerMoudle!=null)
{
timerMoudle.Play(true);
}
return timerMoudle;
}
///
/// 释放计时器
///
/// 计时器flag
/// 是否彻底销毁
public void DisposeTimer(string flag,bool isDestroy=false)
{
TimerMoudle timerMoudle = GetTimer(flag);
if (timerMoudle!=null)
{
timerMoudle.Dispose(isDestroy);
}
}
///
/// 得到计时器
///
/// 计时器flag
///
public TimerMoudle GetTimer(string flag)
{
if (timerDict.ContainsKey(flag))
{
return timerDict[flag];
}
return null;
}
void Update()
{
OnUpdateEvent?.Invoke();
}
private void OnDestroy()
{
OnUpdateEvent = null;
if (timerDict!=null&&timerDict.Count>0)
{
TimerMoudle[] timerMoudles = timerDict.Values.ToArray();
for (int i = timerMoudles.Length-1; i >=0 ; i--)
{
TimerMoudle timerMoudle = timerMoudles[i];
timerMoudle.Dispose(true);
}
timerMoudles = null;
}
timerDict = null;
timerPool.Clear();
timerPool = null;
}
public class TimerMoudle
{
private string m_flag;
private float m_maxTimer;
private float m_curTimer;
private bool _isPlaying;
///
/// 进度回调
///
private Action progressAct;
///
/// 结束回调
///
private Action completeAct;
///
/// 计时器标识符
///
public string flag
{
get{return m_flag;}
private set { m_flag = value; }
}
///
/// 计时器的最大时间
///
public float maxTimer
{
get { return m_maxTimer; }
private set { m_maxTimer = value; }
}
///
/// 当前时间
///
public float curTimer
{
get { return m_curTimer; }
private set { m_curTimer = value; }
}
///
/// 是否正在计时
///
public bool isPlaying
{
get
{
return _isPlaying;
}
private set
{
_isPlaying = value;
}
}
///
/// 是否循环计时
///
public bool isLoop = false;
public TimerMoudle(string _flag,float _maxTimer)
{
flag = _flag;
maxTimer = _maxTimer;
curTimer = 0;
isPlaying = false;
}
public TimerMoudle ReInit(string _flag,float _maxTimer)
{
flag = _flag;
maxTimer = _maxTimer;
curTimer = 0;
isPlaying = false;
OnUpdateEvent -= OnUpdate;
isLoop = false;
return this;
}
///
/// 计时结束回调
///
///
///
public TimerMoudle OnComplete(Action act)
{
completeAct = act;
return this;
}
///
/// 计时进度回调
///
///
///
public TimerMoudle OnProgress(Action act)
{
progressAct = act;
return this;
}
///
/// 打开计时器
///
/// 是否重新计时
///
public TimerMoudle Play(bool restart=false)
{
if (restart)
{
curTimer = 0;
}
isPlaying = true;
OnUpdateEvent += OnUpdate;
return this;
}
///
/// 计时器暂停
///
///
public TimerMoudle Pause()
{
isPlaying = false;
OnUpdateEvent -= OnUpdate;
return this;
}
///
/// 计时器停止
///
///
public TimerMoudle Stop()
{
curTimer = 0;
isPlaying = false;
OnUpdateEvent -= OnUpdate;
return this;
}
private void OnUpdate()
{
curTimer += Time.deltaTime;
curTimer = curTimer > maxTimer ? maxTimer : curTimer;
progressAct?.Invoke(curTimer,maxTimer);
if (curTimer>=maxTimer)
{
completeAct?.Invoke();
if (isLoop)
{
curTimer = 0;
}
else
{
Stop();
}
}
}
///
/// 关闭计时器
///
///
public void Close(bool isDestroy=false)
{
Stop();
flag = null;
progressAct = null;
completeAct = null;
if (isDestroy||timerPool.Count>=instance.poolMaxCount)
{
return;
}
timerPool.Add(this);
}
}
}
public static class TimerMoudleExpand
{
///
/// 释放计时器
///
///
///
public static void Dispose(this TimerManager.TimerMoudle timerMoudle,bool isDestroy=false)
{
timerMoudle?.Close(isDestroy);
timerMoudle=null;
}
}
TimerManager.TimerMoudle tm=TimerManager.instance.CreateTimer("TestFlag", 5).OnProgress((float cur, float max) =>
{
Debug.Log("TimerFlag curTime:"+cur+"maxTime:"+max);
}).OnComplete(() =>
{
Debug.Log("TestFlag: Over");
});
计时器使用结束要记得释放计时器 即tm.Dispose();