Unity计时器

/***
 * 
 *    Title: MXFramework
 *           主题: 计时器
 *    Description: 
 *           功能:计时
 * 
 *    Date: 2019
 *    Version: v1.3.0版本
 *    Modify Recoder: 
 *      
 */

using UnityEngine;

namespace Mx.Util
{
    public delegate void CompleteEvent();
    public delegate void UpdateEvent(float t);

    /// <summary>计时器</summary>
    public class TimeUtil : MonoBehaviour
    {
        #region 数据申明

        /// <summary>是否打印Log</summary>
        private bool isLog = true;

        /// <summary>更新计时器事件</summary>
        private UpdateEvent updateEvent;

        /// <summary>计时器完成委托</summary>
        private CompleteEvent onCompleted;

        /// <summary>计时时间</summary>
        private float timeTarget;

        /// <summary>开始计时时间</summary>
        private float timeStart;

        /// <summary>现在时间</summary>
        private float timeNow;

        /// <summary>计时偏差</summary>
        private float offsetTime;

        /// <summary>是否开始计时</summary>
        private bool isTimer;

        /// <summary>计时结束后是否销毁</summary>
        private bool isDestory = true;

        /// <summary>计时是否结束</summary>
        private bool isEnd;

        /// <summary>是否忽略时间速率</summary>
        private bool isIgnoreTimeScale = true;

        /// <summary>是否重复</summary>
        private bool isRepeate;

        /// <summary>暂停时间</summary>
        private float pauseTime;

        private float GetTime { get { return isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.time; } }
        private float now;

        #endregion

        #region Unity函数

        private void Update()
        {
            if (isTimer)
            {
                timeNow = GetTime - offsetTime;
                now = timeNow - timeStart;
                if (updateEvent != null) updateEvent(Mathf.Clamp01(now / timeTarget));
                if (now > timeTarget)
                {
                    if (onCompleted != null) onCompleted();
                    if (!isRepeate) Destory();
                    else ReStartTimer();
                }
            }
        }

        private void OnApplicationPause(bool isPause)
        {
            if (isPause) { PauseTimer(); }
            else { ConnitueTimer(); }
        }

        #endregion

        #region 计时器逻辑

        /// <summary>获取剩余时间</summary>
        public float GetLeftTime()
        {
            return Mathf.Clamp(timeTarget - now, 0, timeTarget);
        }

        /// <summary>计时结束</summary>
        public void Destory()
        {
            isTimer = false;
            isEnd = true;
            if (isDestory) Destroy(gameObject);
        }

        /// <summary>暂停计时</summary>
        public void PauseTimer()
        {
            if (isEnd) { if (isLog) Mx.Log.DebugManager.LogWarning("计时已经结束!"); }

            else
            {
                if (isTimer)
                {
                    isTimer = false;
                    pauseTime = GetTime;
                }
            }
        }

        /// <summary>继续计时</summary>
        public void ConnitueTimer()
        {
            if (isEnd) { if (isLog) Mx.Log.DebugManager.LogWarning("计时已经结束!请从新计时!"); }

            else
            {
                if (!isTimer)
                {
                    offsetTime += (GetTime - pauseTime);
                    isTimer = true;
                }
            }
        }

        /// <summary>重新启动定时器</summary>
        public void ReStartTimer()
        {
            timeStart = GetTime;
            offsetTime = 0;
        }

        /// <summary>更改目标时间</summary>
        public void ChangeTargetTime(float time)
        {
            timeTarget += time;
        }

        /// <summary>
        /// 开始计时
        /// </summary>
        /// <param name="time">倒计时时间</param>
        /// <param name="onCompleredEvent">计时完成回调</param>
        /// <param name="update">更新事件</param>
        /// <param name="isIgnoreTimeScale">是否忽略时间速率</param>
        /// <param name="isRepeate">是否重复</param>
        /// <param name="isDestory">倒计时完成后是否删除</param>
        public void StartTiming(float time, CompleteEvent onCompleredEvent, UpdateEvent update = null, bool isIgnoreTimeScale = true, bool isRepeate = false, bool isDestory = true)
        {
            timeTarget = time;
            if (onCompleredEvent != null)
                onCompleted = onCompleredEvent;
            if (update != null)
                updateEvent = update;
            this.isDestory = isDestory;
            this.isIgnoreTimeScale = isIgnoreTimeScale;
            this.isRepeate = isRepeate;

            timeStart = GetTime;
            offsetTime = 0;
            isEnd = false;
            isTimer = true;
        }

        /// <summary>
        /// 创建计时器
        /// </summary>
        /// <param name="gobjName">计时器名字</param>
        public static TimeUtil CreateTimer(string gobjName = "TimeUtil")
        {
            GameObject g = new GameObject(gobjName);
            TimeUtil timer = g.AddComponent<TimeUtil>();
            return timer;
        }

        #endregion

    }//class_end

}

Unity QQ交流群:299412191 欢迎对Unity感兴趣的同学加入.

posted @ 2020-10-12 12:49  DaLiangChen  阅读(202)  评论(0编辑  收藏  举报