/**************************************************************************** * Copyright (c) 2017 snowcold * Copyright (c) 2017~2024 liangxiegame UNDER MIT LICENSE * https://github.com/akbiggs/UnityTimer * * https://qframework.cn * https://github.com/liangxiegame/QFramework * https://gitee.com/liangxiegame/QFramework ****************************************************************************/ using System; using System.Collections.Generic; using UnityEngine; namespace QFramework.TimeExtend { public class Timer { static List timers = new List(); private Action UpdateEvent; private System.Action EndEvent; /// /// 用户设定的定时时长 /// private float mTime = -1; /// /// 是否循环执行 /// private bool mLoop; /// /// 是否忽略Timescale /// private bool mIgnorTimescale; /// /// 用户指定的定时器标志,便于手动清除、暂停、恢复 /// private readonly string mFlag; public static TimerDriver Driver = null;//拿驱动器的引用只是为了初始化驱动器 /// /// 获得当前时间 /// private float CurrentTime => mIgnorTimescale ? Time.realtimeSinceStartup : UnityEngine.Time.time; /// /// 缓存时间 /// private float mCachedTime; /// /// 已经流逝的时光 /// float mTimePassed; /// /// 计时器是否结束 /// private bool mIsFinish = false; /// /// 计时器是否暂停 /// private bool mIsPause = false; private const bool ShowLog = true; /// /// 构造定时器 /// /// 定时时长 /// 定时器标识符 /// 是否循环 /// 是否忽略TimeScale private Timer(float time, string flag, bool loop = false, bool ignorTimescale = true) { if (null == Driver) Driver = TimerDriver.Get; //初始化Time驱动 mTime = time; mLoop = loop; mIgnorTimescale = ignorTimescale; mCachedTime = CurrentTime; if (timers.Exists((v) => { return v.mFlag == flag; })) { if (ShowLog) Debug.LogWarningFormat("【TimerTrigger(容错)】:存在相同的标识符【{0}】!", flag); } mFlag = string.IsNullOrEmpty(flag) ? GetHashCode().ToString() : flag;//设置辨识标志符 } /// /// 刷新定时器 /// private void Update() { if (!mIsFinish && !mIsPause) //运行中 { mTimePassed = CurrentTime - mCachedTime; if (null != UpdateEvent) UpdateEvent.Invoke(Mathf.Clamp01(mTimePassed / mTime)); if (mTimePassed >= mTime) { if (null != EndEvent) EndEvent.Invoke(); if (mLoop) { mCachedTime = CurrentTime; } else { Stop(); } } } } /// /// 回收定时器 /// private void Stop() { if (timers.Contains(this)) { timers.Remove(this); } mTime = -1; mIsFinish = true; mIsPause = false; UpdateEvent = null; EndEvent = null; } #region-------------UpdateAllTimer--------------- public static void UpdateAllTimer() { for (int i = 0; i < timers.Count; i++) { if (null != timers[i]) { timers[i].Update(); } } } #endregion } public class TimerDriver : MonoBehaviour { #region 单例 private static TimerDriver mInstance; public static TimerDriver Get { get { if (null == mInstance) { mInstance = FindObjectOfType() ?? new GameObject("TimerEntity").AddComponent(); } return mInstance; } } private void Awake() { mInstance = this; } #endregion private void Update() { Timer.UpdateAllTimer(); } } }