[Unity]記一個倒數計時介面

根结点可不就是孤儿發表於2024-07-23

1.介紹

遊戲開發時還是蠻經常會遇到與時間有關的功能,最近整理了下把遊戲線上的倒數計時抽出了一個介面。
線上遊戲的倒數計時通用需求一般有:
1).倒數計時的時間,比如樹的重生長時間為3分鐘,角色死亡復活倒數計時需要30秒..
2).可以暫停的功能,比如單機遊戲點開設定,那麼樹的重生長倒數計時應該停止;也可以不使用暫停功能,但要提供暫停功能..
3).提供倒數計時生命週期的監聽回撥功能,提供在倒數計時開始時、倒數計時暫停時、倒數計時完成時的監聽介面。

開始時的監聽大多與事件的結果有關,規範性還是寫上,比如在樹被砍倒,呼叫動畫和道具邏輯,然後啟動重生長倒數計時,開始監聽呼叫倒數計時UI滑鼠懸停在樹時顯示,遊戲暫停時呼叫重生長的UI、邏輯、動畫等暫停,倒數計時結束時,樹重新到原樣,同時關閉倒數計時。

2.實現

整體使用一個表裡二層的結構來實現上面需求,其中需要一個實現倒數計時功能的裡層類DownClock,將功能及資料封裝在這個類中,提供一些操控介面給表層類TimeMgr,TimeMgr將管理所有的DownClock,併為外部功能模組提供介面。

DownClock類的實現:

點選檢視程式碼
public class DownClock
{
    bool isPause = false;
    bool isOver = false;
    float timer;
    //各個監聽
    Action OnStart;
    Action OnPause;
    Action OnResume;
    Action OnComplete;
    public DownClock(float _timer, Action _OnComplete = null)
    {
        timer = _timer;
        OnComplete = _OnComplete;
    }
    public DownClock(float _timer, Action _OnStart = null, Action _OnPause = null, Action _OnResume = null, Action _OnComplete = null)
    {
        timer = _timer;
        OnStart = _OnStart;
        OnPause = _OnPause;
        OnResume = _OnResume;
        OnComplete = _OnComplete;
        OnStart?.Invoke();
    }
    //依託於TimeMgr的mono update
    public void TimeDown(float delta)
    {
        if (isOver || isPause) return;
        timer -= delta;
        if (timer < 0)
        {
            timer = 0f;
            isPause = true;
            isOver = true;
            OnComplete?.Invoke();
        }
    }
    //一些對外功能介面
    public bool GetIsOver()
    {
        return isOver;
    }
    public float GetTimer()
    {
        return timer;
    }
    public void AddTime(float value)
    {
        timer += value;
    }
    public void ResumeClock()
    {
        isPause = false;
        OnResume?.Invoke();
    }
    public void PauseClock()
    {
        isPause = true;
        OnPause?.Invoke();
    }
}

TimeMgr類的部分實現:

點選檢視程式碼
public partial class TimeMgr : Singleton<TimeMgr>
{
    void Awake()
    {
        base.Awake();
        DontDestroyOnLoad(gameObject);
    }
    void Update()
    {
        UpdateDownClocks();
    }
    //這裡用List寫了個簡單的管理與對外介面
    public List<DownClock> down_clocks = new List<DownClock>();
    public void UpdateDownClocks()
    {
        if (down_clocks.Count == 0) return;
        //遍歷所有鍾,結束的刪除,其餘的傳入delta time倒數計時
        for (int i = 0; i < down_clocks.Count; i++)
        {
            DownClock clock = down_clocks[i];
            if (clock.GetIsOver())
            {
                down_clocks.Remove(clock);
                continue;
            }
            clock.TimeDown(Time.deltaTime);
        }
    }
    public void AddDownClock(float timer, Action _OnComplete = null)
    {
        DownClock clock = new DownClock(timer, _OnComplete);
        down_clocks.Add(clock);
    }
    public void AddDownClock(float timer, Action _OnStart = null, Action _OnPause = null, Action _OnResume = null, Action _OnComplete = null)
    {

        DownClock clock = new DownClock(timer,_OnStart,_OnPause,_OnResume,_OnComplete);
        down_clocks.Add(clock);
    }
}
根據不同的功能需求,還可以再對該結構和管理模式進行最佳化適配。

相關文章