計時和倒計時,開始、進度及結束回調,計時類型,同時多個計時器計時...
using UnityEngine;
using System.Collections;
using System;
using WillData;
/// <summary>
/// 計時器工具類
/// </summary>
public class Timer : MonoBehaviour
{
#region config
/// <summary>
/// 計時器開始計時
/// </summary>
public ClientData<float> TimerStartCallback;
/// <summary>
/// 計時器計時進度
/// </summary>
public ClientData<float> TimeProcessCallback;
/// <summary>
/// 計時器計時結束
/// </summary>
public ClientData<float> TimerCompletedCallback;
/// <summary>
/// 當前計時器時間
/// </summary>
public float _Now;
public TimerType _timerType;
bool _isLog = true;
/// <summary>
/// true:計時;false:倒計時
/// </summary>
bool _Dir;
float _Start;
float _Pause;
/// <summary>
/// 計時時間
/// </summary>
float _Target;
/// <summary>
/// 時間偏移量
/// </summary>
float _Offset = 0;
float _NowTime;
/// <summary>
/// 是否開始計時
/// </summary>
bool _isTimer;
/// <summary>
/// 計時是否結束
/// </summary>
bool _isEnd;
/// <summary>
/// 忽略時間速率
/// </summary>
bool _isIgnoreTimeScale = true;
/// <summary>
/// 是否重複計時
/// </summary>
bool _isRepeate;
float _Time
{
get { return _isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.time; }
}
#endregion
void Update()
{
if (_isTimer)
{
TimeProcessCallback?.Invoke(_Now);
if (_Dir)
{
_NowTime = _Time - _Offset;
_Now = _NowTime - _Start;
if (_Now > _Target)
{
switch (_timerType)
{
case TimerType.TimeOut:
break;
case TimerType.CountDown:
if (GameData.ServerData.state == GameState.count)
TimerCompletedCallback?.Invoke(0);
break;
case TimerType.Waiting:
break;
case TimerType.Choice:
break;
case TimerType.Loading:
break;
case TimerType.Playing:
if (GameData.ServerData.state == GameState.play)
TimerCompletedCallback?.Invoke(0);
break;
case TimerType.Ending:
if (GameData.ServerData.state == GameState.end)
TimerCompletedCallback?.Invoke(0);
break;
}
if (!_isRepeate)
{
TimeOver();
}
else
{
ResetTimer();
}
}
}
else
{
_NowTime = _Time - _Offset;
_Now = _Target - (_NowTime - _Start);
if (_Now <= 0)
{
switch (_timerType)
{
case TimerType.TimeOut:
break;
case TimerType.CountDown:
if (GameData.ServerData.state == GameState.count)
TimerCompletedCallback?.Invoke(0);
break;
case TimerType.Waiting:
break;
case TimerType.Choice:
break;
case TimerType.Loading:
break;
case TimerType.Playing:
if (GameData.ServerData.state == GameState.play)
TimerCompletedCallback?.Invoke(0);
break;
case TimerType.Ending:
if (GameData.ServerData.state == GameState.end)
TimerCompletedCallback?.Invoke(0);
break;
}
if (!_isRepeate)
{
TimeOver();
}
else
{
ResetTimer();
}
}
}
}
}
/// <summary>
/// 創建計時器
/// </summary>
/// <param name="timerType">計時器類型</param>
/// <returns></returns>
public static Timer CreateTimer(TimerType timerType)
{
GameObject g = new GameObject(timerType.ToString());
Timer timer = g.AddComponent<Timer>();
timer._timerType = timerType;
return timer;
}
public void EventHandler(ClientData<float> StartCallback = null, ClientData<float> ProcessCallback = null, ClientData<float> CompletedCallback = null)
{
TimerStartCallback += StartCallback;
TimerCompletedCallback += CompletedCallback;
TimeProcessCallback += ProcessCallback;
}
public void StartTimer(float time, bool dir = false, bool isIgnoreTimeScale = true, bool isRepeate = false)
{
Debug.Log(_timerType + " 開始計時。");
TimerStartCallback?.Invoke(time);
_Dir = dir;
_Target = time;
_Start = _Time;
_Offset = 0;
_isIgnoreTimeScale = isIgnoreTimeScale;
_isRepeate = isRepeate;
_isEnd = false;
_isTimer = true;
}
void OnApplicationPause(bool state)
{
if (state)
{
Pause();
}
else
{
Timing();
}
}
public void Pause()
{
if (_isEnd)
{
if (_isLog)
{
Debug.Log("Timer is over!");
}
}
else
{
if (_isTimer)
{
_isTimer = false;
_Pause = _Time;
}
}
}
public void Timing()
{
if (_isEnd)
{
if (_isLog)
{
Debug.Log("Timer is over!");
}
}
else
{
if (!_isTimer)
{
_Offset += (_Time - _Pause);
_isTimer = true;
}
}
}
public void ResetTimer()
{
_Start = _Time;
_Offset = 0;
}
public void TimeOver()
{
_isTimer = false;
_isEnd = true;
}
}
namespace WillData
{
public delegate void ClientData();
public delegate void ClientData<T>(T data);
/// <summary>
/// 計時器類型
/// </summary>
public enum TimerType
{
TimeOut,
CountDown,
Waiting,
Choice,
Loading,
Playing,
Ending
}
}