我欲穿花寻路 直入白云深处

[Unity]记一个倒计时接口

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);
    }
}
根据不同的功能需求,还可以再对该结构和管理模式进行优化适配。
posted @ 2024-07-23 20:01  根结点可不就是孤儿  阅读(66)  评论(0编辑  收藏  举报