[Unity]计时器
[Unity] Utilities 之 Timer
参考资料:https://github.com/akbiggs/UnityTimer
1.设计思路
通过调用Timer.Register()方法,生成新的timer实例并将其存储在TimerManager中,TimerManager负责更新所有timer。
TimerManager只存在一个实例,而Timer可以有很多个。
Timer 中的 Register方法
public static Timer Register (float duration, Action onComplete, Action onUpdate = null,
bool isLooped = false, bool useRealTime = false, MonoBehaviour autoDestroyerOwner = null) {
// Lazy Initialize.
// Initialize TimerMagr Instance.
if (TimerMgrInstance == null) {
TimerMgrInstance = (new GameObject ("_TimerManager")).AddComponent<TimerManager> ();
}
if(TimerMgrInstance == null)
Debug.LogError("NULL TimerMgrInstance");
// create new Timer Instance and add to TimerMgr
Timer timer = new Timer (duration, onComplete, onUpdate, isLooped, useRealTime, autoDestroyerOwner);
TimerMgrInstance.RegisterTimer (timer);
return timer;
}
TimerManager 中的 Update方法
private void UpdateAllTimers () {
for (int i = 0; i < m_timers.Count; i++) {
m_timers[i].Update ();
}
m_timers.RemoveAll (t => t.isDone);
}
时间计算
private void Update () {
// 确然timer是否结束
if (isDone) { return; }
// 确认timer是否暂停
if (isPaused) {
m_StartTime += GetTimeDelta ();
m_LastUpdateTime = GetWorldTime ();
return;
}
// 记录上一帧的时间
m_LastUpdateTime = GetWorldTime ();
m_OnUpdate?.Invoke ( /* GetTimeElapsed () */ );
// 确认timer是否完成
if (GetWorldTime () >= GetFireTime ()) {
m_OnComplete?.Invoke ();
// 确定timer是否循环
if (isLooped) {
m_StartTime = GetWorldTime ();
} else {
isCompleted = true;
}
}
}
2.总结
- 通过简单的应用接口就可以生成一个timer,无需继承Monobehaviour。
- 自定义回调函数可以实现动画、计时等功能。无动画功能的DOTWeen?
- 支持暂停、继续、停止执行timer的操作。
在游戏中,延时无处不在。Unity提供协程函数、Invoke函数,但都要继承Monobehviour,且限制多。
通过此Timer工具,温习了一下基于Time.time的时间计算,后面的游戏设计中都会用到此工具。