Unity中使用Timer实现延迟调用函数

需求背景

在Unity中实现延迟调用函数的方法,据我所知有三种

  1. 使用协程中的yield return
  2. 使用Invoke
  3. 使用DoTween中的Sequence

但是如果我想一次性添加多个函数,并且在每个函数都会延迟,延迟时间各不相同,这样使得我们不得不封装,且每遇到一种情况都会封装一次,这样是不能复用,且书写负责不易阅读的。

设计思路

使用自定义的Timer,实现函数延迟调用是可以的,但是想要添加多个,且时间不同,使用Timer的书写也会变得复杂,这个时候我们可以再次封装一个CallbackSequence,模仿Dotween的Sequence(其实就是重复造轮子)

具体实现

对外接口
        /// <summary>
        /// 添加间隔
        /// </summary>
        /// <param name="interval"></param>
        public void AppendInterval(float interval)
        {
            curInterval += interval;
        }

        /// <summary>
        /// 添加回调
        /// </summary>
        /// <param name="callback"></param>
        public void AppendCallback(Action callback)
        {
            float tempInterval = curInterval;
            Timer timer = new Timer(tempInterval, callback);
            timers.Add(timer);
        }

        /// <summary>
        /// 开始执行
        /// </summary>
        public void Start()
        {
            Reset();
            foreach (var timer in timers)
            {
                timer.Start();
            }
        }

        /// <summary>
        /// 注销
        /// </summary>
        public void Dispose()
        {
            for (int i = 0; i < timers.Count; i++)
            {
                timers[i].Stop();
                timers[i].Dispose();
                timers[i] = null;
            }
            timers.Clear();
            timers = null;
        }
对内接口
        /// <summary>
        /// 重置
        /// </summary>
        private void Reset()
        {
        }
全部代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

namespace JunFramework
{
    public class CallbackSequence: IDisposable
    {
        private float curInterval;
        private List<Timer> timers;

        public CallbackSequence()
        {
            curInterval = 0f;
            timers = new List<Timer>();
        }

        /// <summary>
        /// 添加间隔
        /// </summary>
        /// <param name="interval"></param>
        public void AppendInterval(float interval)
        {
            curInterval += interval;
        }

        /// <summary>
        /// 添加回调
        /// </summary>
        /// <param name="callback"></param>
        public void AppendCallback(Action callback)
        {
            float tempInterval = curInterval;
            Timer timer = new Timer(tempInterval, callback);
            timers.Add(timer);
        }

        /// <summary>
        /// 开始执行
        /// </summary>
        public void Start()
        {
            Reset();
            foreach (var timer in timers)
            {
                timer.Start();
            }
        }

        /// <summary>
        /// 注销
        /// </summary>
        public void Dispose()
        {
            for (int i = 0; i < timers.Count; i++)
            {
                timers[i].Stop();
                timers[i].Dispose();
                timers[i] = null;
            }
            timers.Clear();
            timers = null;
        }

        /// <summary>
        /// 重置
        /// </summary>
        private void Reset()
        {
        }
    }
}

用例测试

实现代码

点击查看代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using JunFramework;

public class CallbackSequenceExample : MonoBehaviour
{
    private CallbackSequence sequence;
    void Start()
    {
        sequence = new CallbackSequence();
        sequence.AppendCallback(() => Debug.Log("第一"));
        sequence.AppendInterval(1f);
        sequence.AppendCallback(() => Debug.Log("第二"));
        sequence.AppendInterval(1f);
        sequence.AppendCallback(() => Debug.Log("第三"));
        sequence.AppendInterval(1f);
        sequence.AppendInterval(1f);
        sequence.AppendCallback(() => Debug.Log("第四"));
        sequence.Start();
    }

    // Update is called once per frame
    void Update()
    {
        Timer.Tick(Time.deltaTime);
    }
}

测试结果

image

总结

此CallbakSequence是我的Timer的拓展工具,也是为了测试我的Timer是否可用。虽然是模仿的Dotween的Sequence,但重复造轮子的路肯定都会走一遍的。我们在延迟多个函数,且每个函数延迟时间不同时,即可采用此模块。

posted @ 2023-03-12 11:46  军酱不是酱  阅读(333)  评论(0编辑  收藏  举报