Unity之计时器功能

注释很详细,不做解释了

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
	
}
原文地址:https://www.cnblogs.com/weiqiangwaideshijie/p/7929102.html