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感兴趣的同学加入.