注释很详细,不做解释了
using UnityEngine; using System.Collections; using System; using System.Collections.Generic; ///<summary> /// 计时完成时的委托 ///</summary> public delegate void CompleteTimerDel(); ///<summary> /// 计时中的委托 ///</summary> public delegate void UpdateTimerDel(float t); public class TimerMgr : MonoBehaviour { ///<summary> /// 储存全局的计时器 ///</summary> private static Dictionary <string,TimerMgr> _instanceDic=new Dictionary <string,TimerMgr>(); ///<summary> /// 计时完成时去调用 ///</summary> private CompleteTimerDel _onCompletTimerHandle; ///<summary> /// 计时中去调用 ///</summary> private UpdateTimerDel _onUpdateTimerHandle; ///<summary> /// 是否打印计时器中的Log信息 ///</summary> private bool _isLog=true; ///<summary> /// 计时时间 ///</summary> private float _timerTarget=0f; ///<summary> /// 开始计时的时间 ///</summary> private float _timerStart=0f; ///<summary> /// 现在等时间 ///</summary> private float _timerNow=0f; //<summary> ///计时等偏差 ///</summary> private float _offsetTimer=0; ///<summary> /// 是否开始计时 ///</summary> private bool _isTimer=false; ///<summary> /// 结束计时之后释放销毁 ///</summary> private bool _isDestroy=false; ///<summary> /// 计时是否结束 ///</summary> private bool _isEnd=false; ///<summary> ///是否循环计时 ///</summary> private bool _isRepeate=false; ///<summary> /// 是否忽略时间缩放 ///</summary> private bool _isIngoreTimeScale=false; ///<summary> ///保留暂停时候的时间 ///</summary> private float _pauseTimer=0f; ///<summary> /// 游戏进行等时间 ///</summary> private float time{ get{ return _isIngoreTimeScale?Time.realtimeSinceStartup:Time.time; } } private float _now; void Update() { if(_isTimer) { _timerNow=time-_offsetTimer; _now=_timerNow-_timerStart; if(_onUpdateTimerHandle!=null) _onUpdateTimerHandle(Mathf.Clamp01(_now/_timerTarget)); if(_now>_timerTarget) { if(_onCompletTimerHandle!=null) _onCompletTimerHandle(); if(!_isRepeate) MyResult(); else ReStartTimer(); } } } ///<summary> /// 得到一个全局的计时器 ///</summary> public static TimerMgr GetIGobalnstance(string timerName) { if(!_instanceDic.ContainsKey(timerName)) { GameObject timerGo=new GameObject (timerName); TimerMgr timerMgr =timerGo.AddComponent<TimerMgr>(); DontDestroyOnLoad(timerGo); _instanceDic.Add(timerName,timerMgr); } return _instanceDic[timerName]; } ///<summary> /// 得到一个非全局的计时器 ///</summary> public static TimerMgr GetTimerMgr(string timerName) { GameObject timerGo=new GameObject (timerName); TimerMgr timerMgr=timerGo.AddComponent<TimerMgr>(); return timerMgr; } ///<summary> /// 重新开始计时 ///</summary> private void ReStartTimer() { _timerStart=time; _offsetTimer=0f; } ///<summary> ///计时结果 ///</summary> private void MyResult() { _isTimer=false; _isEnd=true; if(_isDestroy) Destroy(gameObject); } private void OnApplicationPause(bool isPause) { if (isPause) { PauseTimer(); } else { ContinueTimer(); } } #region 对外接口 获得计时器等信息 ///<summary> /// 开始启动计时器 ///</summary> /// <param name="time">计时的时间</param> /// <param name="completeTimeHandl">计时完成的委托</param> /// <param name="updateTimeHandle=">计时中的委托</param> /// <param name="isIgnoreTimeScale=">是否忽略时间缩放</param> /// <param name="isRepeate=">是否循环计时</param> /// <param name="isDestroy=">是否计时完成之后销毁此计时器</param> public void StartTimer(float targetTime,CompleteTimerDel completeTimeHandl,UpdateTimerDel updateTimeHandle=null,bool isIgnoreTimeScale=true,bool isRepeate=false,bool isDestroy=false) { _timerTarget=targetTime; if(completeTimeHandl!=null) _onCompletTimerHandle=completeTimeHandl; if(updateTimeHandle!=null) _onUpdateTimerHandle=updateTimeHandle; this._isIngoreTimeScale=isIgnoreTimeScale; this._isRepeate=isRepeate; this._isDestroy=isDestroy; _timerStart=time; _offsetTimer=0f; _isEnd=false; _isTimer=true; } ///<summary> /// 改变目标时间 ///</summary> public void ChangeTargetTime(float time) { _timerTarget+=time; } ///<summary> /// 得到剩下的时间 ///</summary> public float GetLeftTime() { return Mathf.Clamp(_timerTarget-_now,0,_timerTarget); } ///<summary> /// 继续计时 ///</summary> public void ContinueTimer() { if(_isEnd) { if(_isLog) Debug.Log("计时器已经结束计时"); }else{ if(!_isTimer) { _offsetTimer+=(time-_pauseTimer); _isTimer=true; } } } ///<summary> /// 暂停计时 ///</summary> public void PauseTimer() { if(_isEnd) { if(_isLog) Debug.Log("计时器已经结束计时"); }else{ if(_isTimer) { _isTimer=false; _pauseTimer=time; } } } #endregion }