计时系统
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 中的计时器