导入 TimerModule 计时器模块
This commit is contained in:
@@ -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 性能
|
||||
Reference in New Issue
Block a user