[Unity]计时器

[Unity] Utilities 之 Timer

参考资料:https://github.com/akbiggs/UnityTimer

1.设计思路

[Unity]计时器
通过调用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的时间计算,后面的游戏设计中都会用到此工具。