导入 TimerModule 计时器模块

This commit is contained in:
2026-06-18 22:50:46 +08:00
parent fbc7e66491
commit 0dc5889417
21 changed files with 1334 additions and 1 deletions
+143
View File
@@ -0,0 +1,143 @@
# TimerModule 接入说明
基于 UnityGameFramework 的通用定时器组件插件,支持延迟执行、循环执行、按归属对象批量取消等功能。
## 导入步骤
1. 将 `Assets/Plugins/TimerModule/` 整个目录导入目标项目
2. 导入后通过 asmref 自动并入 `SepCore.Runtime` 程序集,基座项目仍可正常编译
3. 移除 TimerModule 时只需删除整个目录,不会留下残留引用
## 程序集结构
```
SepCore.Runtime.Timer.asmref → 引用 SepCore.Runtime,使 TimerComponent 与其他基座 Component 平级
```
- 依赖:`UnityGameFramework.Runtime`(框架自带)
- 无第三方依赖,纯 C# 实现
- 命名空间:`SepCore.Timer`
## 场景挂载要求
在 GameFramework 框架的组件挂载对象上(通常是场景中的 `GameEntry` 对象):
1. 添加 `TimerComponent` 组件
2. 组件会通过 `Update()` 自动驱动,无需额外初始化
3. AddComponentMenu 路径:`Game Main/Timer`
## API 使用方式
```csharp
using SepCore.Timer;
// 获取组件引用
var timer = GameEntry.GetComponent<TimerComponent>();
// 1. 一次性延迟执行
timer.ScheduleOnce(2f, () =>
{
Debug.Log("2秒后执行");
});
// 2. 无限循环(默认)
timer.ScheduleRepeat(1f, () =>
{
Debug.Log("每秒执行一次");
});
// 3. 指定次数循环(首次延迟 = 循环间隔)
timer.ScheduleRepeat(0.5f, () =>
{
Debug.Log("每0.5秒执行,共执行10次");
}, repeatCount: 10);
// 4. 自定义首次延迟 + 循环间隔
timer.ScheduleRepeat(delay: 3f, interval: 1f, () =>
{
Debug.Log("3秒后开始,然后每秒执行一次");
});
// 5. 使用 unscaledTime(不受 Time.timeScale 影响)
timer.ScheduleRepeat(1f, () =>
{
Debug.Log("暂停时也会执行");
}, timeMode: TimerTimeMode.Unscaled);
// 6. 取消单个任务
TimerHandle handle = timer.ScheduleOnce(5f, Callback);
timer.Cancel(handle); // 提前取消
// 7. 按归属对象批量取消(适合 MonoBehaviour 销毁时清理)
private void OnDestroy()
{
timer.CancelByOwner(this); // 取消所有归属于当前对象的定时器
}
// 8. 全局暂停/恢复
timer.Pause(); // 暂停所有定时器
timer.Resume(); // 恢复所有定时器
// 9. 清理所有
timer.ClearAll();
```
## TimerHandle 说明
- 值类型,可安全作为成员变量存储
- `handle.IsValid` - 检查句柄是否有效
- `TimerHandle.Invalid` - 无效句柄常量
- 实现 `IEquatable<TimerHandle>`,可用于字典键或比较
## 参数说明
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `delay` | float | - | 首次触发前的延迟时间(秒) |
| `interval` | float | - | 循环触发间隔(秒),一次性任务忽略 |
| `repeatCount` | int | -1 | 触发次数:1=一次性,负数=无限循环,0=不创建 |
| `owner` | object | null | 任务归属对象,用于 `CancelByOwner` 批量取消 |
| `timeMode` | TimerTimeMode | Scaled | 时间源:Scaled 受 timeScale 影响,Unscaled 不受影响 |
## 最佳实践
1. **MonoBehaviour 中使用时务必设置 owner**,并在 `OnDestroy` 中调用 `CancelByOwner(this)` 避免回调执行在已销毁对象上
2. **在回调中取消自身是安全的**:回调执行时标记取消,当前帧更新结束后统一清理
3. **精度说明**:定时器基于帧更新,精度受帧率影响,适合游戏逻辑计时,不适合高精度物理模拟
4. **推荐使用便捷方法**:`ScheduleOnce` 和 `ScheduleRepeat` 比直接 `Schedule(TimerTask)` 更清晰
## 编辑器调试功能
TimerModule 内置了完整的 Editor 调试扩展,选中挂载 `TimerComponent` 的对象即可看到:
### 统计信息面板
- **活跃任务总数** - 当前正在运行的任务数量
- **Scaled/Unscaled 分布** - 受时间缩放影响的任务 vs 不受影响的任务
- **无限循环数** - `repeatCount < 0` 的永久任务数量
- **异常任务数** - 回调曾抛出异常的任务(红色高亮)
- **全局运行状态** - 绿色=运行中,橙色=已暂停
### 任务列表可视化
- **ID + 时间模式标签** - 快速识别任务,青色=Scaled,黄色=Unscaled
- **进度条** - 显示剩余时间和当前周期完成进度
- 一次性任务:显示延迟完成度
- 循环任务:显示当前周期进度
- **回调方法名** - `Class.Method` 格式,定位来源
- **归属对象** - 点击可直接 Ping 到场景中的 Owner 对象
- **异常标记** - 曾抛异常的任务会有红色背景警告
### 调试控制
- **暂停/恢复全部** - 一键控制全局定时器
- **单任务取消** - 每个任务右侧的取消按钮,可随时终止
- **清理全部** - 一键清除所有任务(含确认对话框)
## 性能特性
- 回调异常自动捕获并 LogError,不会中断其他任务或游戏
- 帧更新时遍历取消采用反向遍历,避免索引错乱
- 更新期间的删除操作延迟到帧末执行,避免并发问题
- O(n) 线性遍历,适合千级以内任务规模
- Editor 调试面板每帧自动刷新,不影响 Build 性能