【Unity】替代Invoke的定时器,可延迟执行带参方法

【Unity】替代Invoke的定时器,可延迟执行带参方法

游戏开发离不开定时器,一个好用的延时方法对于控制游戏节奏而言尤为重要。但是 Unity 中的 Invoke 方法使用有着诸多缺陷,比如不容易查找引用,无法延时带参方法等。其他的延时方法,诸如协程和 Update 中监控,实现都比较繁琐。

这一个类封装了 Update 监控实现定时器的方法,实际使用时和 Invoke 一样便利,同时解决了 Invoke 不容易查找引用和无法延时带参方法的问题。

TimerManager.GetInstance().StartTimer(1f, methodName);
等效于,
Invoke(“methodName”, 1f);
同时可以使用 delegate 关键字实现带参方法的延时,
TimerManager.GetInstance().StartTimer(1f, delegate { methodName(value); });

TimeManager.cs 代码贴上:

using System;
using System.Collections.Generic;
using UnityEngine;

// 定时器管理类
public class TimerManager : MonoBehaviour
{
   
   
    private List<Timer> poolTimer = new List<Timer>(); // 全部定时器

    // 多线程安全的单例【文章后续有对此处单例写法的更正】
    private static TimerManager timerManager;
    private static readonly object _lock = new object();
    public static TimerManager GetInstance()
    {
   
   
        if (timerManager == null)
        {
   
   
            lock (_lock)
            {
   
   
                if (timerManager == null)
                {
   
   
                    GameObject obj = GameObject.Find("TimerManager");
                    if (obj == null)
                        obj = new GameObject("TimerManager");
                    timerManager = obj.AddComponent<TimerManager>();
                }
            }
        }
        return timerManager;
    }

    /// <summary>
    /// timer 秒后执行一次 timerCallback 函数
    /// </summary>
    /// <param name="timer">延迟执行时间</param>
    /// <param name="timerCallback">延迟执行的函数</param>
    /// <param name="unscaled">默认false,若为true -- 不受timescale缩放影响</param>
    public void StartTimer(float timer, Action timerCallback
### Unity 中 `Invoke` 方法的使用 #### 基础概念 `Invoke` 是 Unity 提供的一个函数,允许开发者在指定的时间延迟后调用另一个方法。此方法通常用于实现简单的定时器功能[^1]。 #### 调用无方法 如果目标方法不需要任何参数,则可以直接通过 `Invoke` 来调用。例如: ```csharp using UnityEngine; public class Example : MonoBehaviour { void Start() { Invoke("SpawnObject", 2); // 在2秒后调用 SpawnObject 方法 } void SpawnObject() { Instantiate(target, new Vector3(0, 2, 0), Quaternion.identity); } } ``` 上述代码展示了如何在启动后的两秒钟内调用 `SpawnObject` 函数[^5]。 #### 注意事项 需要注意的是,在某些情况下无法禁用已经安排好的 `Invoke` 调用。即使设置组件不可用 (`this.enabled = false`) 或者隐藏游戏对象 (`this.gameObject.SetActive(false)`),已计划中的 `Invoke` 并不会自动取消[^2]。 #### 参数方法调用 虽然标准形式下的 `Invoke` 不支持直接参数,但可以通过扩展方式来间接完成这一需求。下面是一个例子展示如何向被调用的方法入字符串和整数作为参数[^3]: ```csharp using UnityEngine; using System.Collections; public class MyScript : MonoBehaviour { void Start() { StartCoroutine(DelayedCall()); } IEnumerator DelayedCall() { yield return new WaitForSeconds(5.0f); // 等待5秒 DoSomething("Hello", 123); // 执行参数方法 } void DoSomething(string message, int number) { Debug.Log(message + " " + number); } } ``` 这里采用了协程的方式替代统的 `Invoke` 实现了参数的功能[^4]。 #### 替代方案 对于更复杂的场景或者需要更高的可靠性时,建议考虑使用 C# 的委托 (Delegates) 和 Lambda 表达式等现代特性代替原始的 `Invoke` 方法。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值