计时系统

Fink Framework 内置一个轻量级但功能完善的计时系统,支持创建可控、可暂停、可回收的多种计时器。所有计时器均基于协程驱动,并具备对象池回收机制,适用于中小型项目中的定时需求。

计时系统主要由以下两个类组成:

  • TimerManager:统一管理所有计时器

  • TimerItem:单个计时器的具体数据结构


1. 核心特性

  • 支持普通计时器(受 Time.timeScale 影响)
  • 支持真实计时器(不受 Time.timeScale 影响)
  • 支持间隔计时(类似 setInterval)
  • 支持一次性计时器(类似 setTimeout)
  • 支持无限循环计时
  • 支持单个计时器的暂停/恢复
  • 支持全部计时器的暂停/恢复
  • 自动对象池回收,性能开销极小
  • 单次协程驱动所有计时器,不会创建额外 Update

2. 计时器类型

计时器分为两类:

类型是否受 TimeScale 影响使用场景
普通计时器角色动作、冷却时间、游戏逻辑等
真实计时器UI 动画、网络心跳、本地倒计时等

3. 基本使用

3.1 创建一个倒计时

int id = TimerManager.Instance.CreateTimer(
    isRealTimer: false,
    allTime: 3000,               // 3 秒
    onOver: () => { Debug.Log("计时结束"); }
);

3.2 创建间隔计时器

int id = TimerManager.Instance.CreateTimer(
    isRealTimer: false,
    allTime: 5000,               // 总共 5 秒
    onOver: () => Debug.Log("全部结束"),
    intervalTime: 1000,          // 每 1 秒执行
    onInterval: () => Debug.Log("间隔执行")
);

3.3 创建无限循环计时器

int id = TimerManager.Instance.CreateInfiniteTimer(
    isRealTimer: true,
    intervalTime: 500,
    onInterval: () => Debug.Log("每 0.5 秒执行一次")
);

3.4 一次性计时器

一次执行,然后自动销毁:

TimerManager.Instance.SetTimeout(
    2000,
    () => Debug.Log("两秒后执行一次")
);

3.5 示例:技能冷却系统

public void StartSkillCD()
{
    TimerManager.Instance.CreateTimer(
        false,
        3000,
        () => Debug.Log("技能冷却完毕"),
        1000,
        () => Debug.Log("技能剩余 1 秒")
    );
}

4. 控制计时器

4.1 暂停单个计时器

TimerManager.Instance.StopTimer(id);

4.2 恢复单个计时器

TimerManager.Instance.StartTimer(id);

4.3 重置计时器

TimerManager.Instance.ResetTimer(id);

4.4 删除计时器

TimerManager.Instance.RemoveTimer(id);


5. 控制全部计时器

5.1 暂停所有计时器

TimerManager.Instance.PauseAll();

5.2 恢复所有计时器

TimerManager.Instance.ResumeAll();


6. TimerItem 数据结构说明

单个计时器内部字段:

public int keyID;             // 唯一 ID
public UnityAction onOver;    // 结束回调
public UnityAction onInterval;// 间隔回调

public int allTime;           // 剩余总时间
public int maxAllTime;        // 初始总时间

public int intervalTime;      // 剩余间隔时间
public int maxIntervalTime;   // 初始间隔时间

public bool isRunning;        // 是否正在运行

TimerItem 由对象池自动分配与回收,无需手动创建和销毁。


7. 协程调度机制

计时系统使用 单个协程 驱动所有计时器:

while (true)
{
    yield return waitForSeconds(0.1f);
    遍历所有 TimerItem
    处理间隔逻辑
    处理总时间逻辑
    执行到期计时器
    回收对象
}

优点:

  • 所有计时器共享一次 Update
  • 不在游戏主循环产生额外开销
  • 对象池减少 GC 产生

8. 注意事项

  • allTime < 0 表示无限计时器(只执行 interval)
  • 间隔计时器的回调可能在一次循环中执行多次(当间隔过短时)
  • 计时器依赖 MonoManager 的协程,不需要挂载在场景中
  • 调整 Time.timeScale 不会影响 realTimerDic 中的计时器