用途
通過TimeSys生成1個Timer。
生成時,可設(shè)置是否立即開始計時、該計時器是否忽略Time.timeScale變化的影響
對于單個計時器,可以:開始計時、暫停計時、繼續(xù)計時、重置時間。
UnityTime相關(guān)的小知識
- FixedUpdate()的執(zhí)行頻率會受Time.timeScale的影響,當(dāng)scale=0時不執(zhí)行。
- Update和LateUpdate不受Time.timeScale的影響。
- Time.deltaTime受Time.timeScale的影響,Time.unscaledDeltaTime不受Time.timeScale的影響。
具體代碼
TimerSys和Timer
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TimerSys
{
private static TimerSys _instance;
public static TimerSys Instance
{
get
{
if (_instance == null)
{
_instance = new TimerSys();
}
return _instance;
}
}
private List<Timer> _timerList;
public TimerSys()
{
_timerList = new List<Timer>();
MonoSys.Instance.AddUpdateEvent(OnUpdateEvent);
}
public void Destroy()
{
MonoSys.Instance?.RemoveUpdateEvent(OnUpdateEvent);
Clear();
_timerList = null;
}
public void Clear()
{
if (_timerList == null)
{
return;
}
foreach (var timer in _timerList)
{
timer.Destroy();
}
_timerList.Clear();
}
public Timer CreateTimer(bool shouldImmediateStart = true, bool shouldIgnoreTimeScale = false)
{
Timer timer = new Timer(shouldImmediateStart, shouldIgnoreTimeScale);
_timerList.Add(timer);
return timer;
}
public bool DestroyTimer(Timer timer)
{
bool destroySuccessfully = false;
if (_timerList.Contains(timer))
{
timer.Destroy();
_timerList.Remove(timer);
destroySuccessfully = true;
}
return destroySuccessfully;
}
private void OnUpdateEvent()
{
if (_timerList != null && _timerList.Count > 0)
{
for (int i = 0; i < _timerList.Count; i++)
{
if (_timerList[i] != null)
{
_timerList[i].UpdateTime();
}
}
}
}
}
public class Timer
{
private float _time;
public float Time
{
get { return _time; }
}
private readonly bool ShouldIgnoreTimeScale;
public bool IsPaused{ get; private set; }
public event Action<float> TimeChangedEvent;
public event Action PauseEvent;
public event Action ContinueEvent;
public Timer(bool shouldImmediateStart, bool shouldIgnoreTimeScale)
{
ShouldIgnoreTimeScale = shouldIgnoreTimeScale;
if (shouldImmediateStart)
{
BeginTime();
}
else
{
Pause();
}
}
public void Destroy()
{
}
// 修改時間
public void UpdateTime()
{
if (!IsPaused)
{
if (ShouldIgnoreTimeScale)
{
ChangeTime(_time + UnityEngine.Time.unscaledDeltaTime);
}
else
{
ChangeTime(_time + UnityEngine.Time.deltaTime);
}
}
}
private void ChangeTime(float time)
{
_time = time;
TimeChangedEvent?.Invoke(_time);
}
// 開始計時
public void BeginTime()
{
Reset();
Continue();
}
// 停止計時
public void Pause()
{
IsPaused = true;
PauseEvent?.Invoke();
}
// 繼續(xù)計時
public void Continue()
{
IsPaused = false;
ContinueEvent?.Invoke();
}
// 重置時間
public void Reset()
{
ChangeTime(0f);
}
// 格式化顯示
public static string FormatStr(float time)
{
int intTime = (int)time;
int hour = intTime / 3600;
int minute = (intTime - 3600 * hour) / 60;
int second = intTime - 3600 * hour - 60 * minute;
string hourStr = hour.ToString().PadLeft(2, '0');
string minuteStr = minute.ToString().PadLeft(2, '0');
string secondStr = second.ToString().PadLeft(2, '0');
string timeStr = string.Format("{0}:{1}:{2}", hourStr, minuteStr, secondStr);
return timeStr;
}
}
MonoSys
用途:讓不繼承MonoBehaviour能使用MonoBehaviour提供的一些方法。(通過注冊事件的方式)
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonoController : MonoBehaviour
{
public event Action ApplicationPauseEvent;
public event Action ApplicationQuitEvent;
public event Action UpdateEvent;
private void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
{
ApplicationPauseEvent?.Invoke();
}
}
private void OnApplicationQuit()
{
ApplicationQuitEvent?.Invoke();
}
private void Update()
{
UpdateEvent?.Invoke();
}
}
public class MonoSys
{
private static MonoSys _instance;
public static MonoSys Instance
{
get
{
if (_instance == null)
{
_instance = new MonoSys();
}
return _instance;
}
}
private MonoController _monoController;
private MonoSys()
{
var parentGo = GameObject.Find("Singleton");
if (parentGo == null)
{
parentGo = new GameObject("Singleton");
UnityEngine.Object.DontDestroyOnLoad(parentGo);
}
GameObject go = new GameObject(nameof(MonoController));
go.transform.SetParent(parentGo.transform);
_monoController = go.AddComponent<MonoController>();
}
public Coroutine StartCoroutine(IEnumerator routine)
{
return _monoController.StartCoroutine(routine);
}
public void StopCoroutine(IEnumerator routine)
{
_monoController.StopCoroutine(routine);
}
public void AddApplicationQuitEvent(Action action)
{
_monoController.ApplicationQuitEvent += action;
}
public void RemoveApplicationQuitEvent(Action action)
{
_monoController.ApplicationQuitEvent -= action;
}
public void AddApplicationPauseEvent(Action action)
{
_monoController.ApplicationPauseEvent += action;
}
public void RemoveApplicationPauseEvent(Action action)
{
_monoController.ApplicationPauseEvent -= action;
}
public void AddUpdateEvent(Action action)
{
_monoController.UpdateEvent += action;
}
public void RemoveUpdateEvent(Action action)
{
_monoController.UpdateEvent -= action;
}
}