【Unity】在Unity中封装计时器功能

简介

在Unity中封装计时器功能

常用方法

  • AlarmAfter(float second, Action callBack) 执行一次
    • second 等待时间
    • callBack 将要执行方法
  • AlarmRepeat(float delay, float repeatInterval, Action callBack) 循环执行
    • delay 第一次执行前延时时间
    • repeatInterval 重复间隔
    • callBack 将要执行方法
  • Stop(Clock clock) 停止某一计时器
  • Dispose() 停止全部计时器

详细代码

Clock

    public class Clock{
        Action onAlarm;

        private readonly ClockType type;
        private readonly float alarmTime1;
        private readonly DateTime alarmTime2 = DateTime.Now;
        private readonly bool repeat;//是否重复
        private readonly float interval = 10;
        private float nextAlarmSecond;

        public bool IsStopped{ get; private set; }

        public Clock(float time, Action callBack){
            type = ClockType.UNITY_TIME_CLOCK;
            alarmTime1 = time;
            onAlarm = callBack;
        }

        public Clock(float time, float interval, Action callBack){
            type = ClockType.UNITY_TIME_CLOCK;
            alarmTime1 = time;
            repeat = true;
            this.interval = interval;
            nextAlarmSecond = time + interval;
            onAlarm = callBack;
        }

        public Clock(DateTime time, Action callBack){
            type = ClockType.DATE_TIME_CLOCK;
            alarmTime2 = time;
            onAlarm = callBack;
        }

        public void Invoke(){
            switch (type){
                case ClockType.DATE_TIME_CLOCK:
                    if (DateTime.Now >= alarmTime2){
                        Alarm(true);
                        IsStopped = true;
                    }

                    break;
                case ClockType.UNITY_TIME_CLOCK:
                    if (repeat){
                        if (Time.time >= nextAlarmSecond){
                            Alarm(false);
                            nextAlarmSecond += interval;
                        }
                    }
                    else{
                        if (Time.time >= alarmTime1){
                            Alarm(true);
                            IsStopped = true;
                        }
                    }

                    break;
            }
        }

        public void Abandon(){
            if (IsStopped){
                return;
            }

            IsStopped = true;
            onAlarm = null;
        }

        private void Alarm(bool once){
            try{
                onAlarm?.Invoke();
            }
            catch (Exception e){
                IsStopped = true;
                onAlarm = null;
                Debug.LogWarning(e.ToString());
            }
            finally{
                if (once){
                    onAlarm = null;
                }
            }
        }
    }

    public enum ClockType{
        DATE_TIME_CLOCK,
        UNITY_TIME_CLOCK,
    }

ClockUtil

    public class ClockUtil : SingletonMonoBehaviour<ClockUtil> {
        readonly List<Clock> clocks = new();

        public Clock AlarmAt(DateTime dateTime, Action callBack) {
            if (dateTime < DateTime.Now) {
                Debug.LogWarning($"不合理的报警时间:dateTime-->{dateTime}");
                return null;
            }

            var clock = new Clock(dateTime, callBack);
            clocks.Add(clock);
            return clock;
        }

        public Clock AlarmAfter(float second, Action callBack) {
            if (second < 0f) {
                Debug.LogWarning($"不合理的报警时间:second-->{second}");
                return null;
            }

            var clock = new Clock(Time.time + second, callBack);
            if (second == 0f) {
                clock.Invoke();
                return clock;
            }

            clocks.Add(clock);
            return clock;
        }

        public Clock AlarmRepeat(float delay, float repeatInterval, Action callBack){
            if (delay < 0f) {
                Debug.LogWarning($"不合理的延迟时间:delay-->{delay}");
                return null;
            }

            if (repeatInterval <= 0f) {
                Debug.LogWarning($"不合理的重复间隔:repeatInterval-->{repeatInterval}");
                return null;
            }

            var clock = new Clock(Time.time + delay, repeatInterval, callBack);
            clocks.Add(clock);
            return clock;
        }

        public void Stop(Clock clock) {
            clock?.Abandon();
        }

        public void Dispose() {
            foreach (var clock in clocks) {
                clock.Abandon();
            }
        }

        private void Update() {
            for (var i = clocks.Count - 1; i >= 0; i--) {
                var clock = clocks[i];
                if (clock.IsStopped) {
                    clocks.RemoveAt(i);
                } else {
                    clock.Invoke();
                }
            }
        }
    }
posted @ 2023-11-22 16:37  星空探险家  阅读(128)  评论(0编辑  收藏  举报