# 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(); // 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`,可用于字典键或比较 ## 参数说明 | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `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 性能