定时器组件
简介
说明
定时器组件是 ET 框架中一个重要的功能组件,它提供了一套完整的定时任务管理方案。主要功能包括:
- 延时执行任务
- 循环定时任务
- 定时器的取消和销毁
核心特性
- 多种定时器类型: 支持一次性定时器、重复性定时器和异步等待定时器
- 异步支持: 提供异步等待接口,支持现代异步编程模式
- 性能优化: 使用高效的数据结构,优化定时器查找和管理
定时器类型
1. 一次性定时器 (OnceTimer)
用于执行一次性的延时任务:
csharp
// 创建一个3秒后执行的定时器
long timerId = timerComponent.NewOnceTimer(TimeInfo.Instance.ClientNow() + 3000, type, args);
2. 重复性定时器 (RepeatedTimer)
用于执行周期性重复的任务:
csharp
// 创建一个每1秒执行一次的定时器
long timerId = timerComponent.NewRepeatedTimer(1000, type, args);
3. 异步等待定时器 (OnceWaitTimer)
用于异步等待特定时间:
csharp
// 异步等待2秒
await timerComponent.WaitAsync(2000);
// 等待到指定时间
await timerComponent.WaitTillAsync(tillTime);
4. 帧定时器
用于每帧执行的任务:
csharp
// 创建一个每帧执行的定时器
long timerId = timerComponent.NewFrameTimer(type, args);
使用建议
短时间等待场景:
- 推荐使用
WaitTillAsync
- 适用于需要逻辑连贯的短时间等待
- 例如:短暂的动画等待、简单的延时效果
- 推荐使用
长时间等待场景:
- 推荐使用
NewOnceTimer
- 适用于需要热更新的长时间等待
- 例如:长时间的游戏状态检查、定期的数据同步
- 推荐使用
循环任务场景:
- 推荐使用
NewRepeatedTimer
- 适用于需要定期执行的任务
- 例如:背包刷新、buff更新等
- 推荐使用
定时器管理
取消定时器
csharp
// 通过定时器ID取消
timerComponent.Remove(ref timerId);
安全性考虑
- 时间检查
- 重复性定时器的最小间隔为100ms
- 小于100ms的时间间隔会触发错误提示
- 取消机制
- 提供
Remove
方法安全地移除定时器
基础用法
接下来将通过MoveComponent
组件来对定时器进行一个简单的使用示例
MoveComponent.cs
csharp
public class MoveComponent : Entity, IAwake, IDestroy
{
}
MoveComponentSystem.cs
csharp
using System;
using UnityEngine;
namespace MH
{
[EntitySystem]
public class MoveComponentAwakeSystem : AwakeSystem<MoveComponent>
{
protected override void Awake(MoveComponent self)
{
}
}
[EntitySystem]
public class MoveComponentDestroySystem : DestroySystem<MoveComponent>
{
protected override void Destroy(MoveComponent self)
{
}
}
public static class MoveComponentSystem
{
}
}
现在来定义一下需求:
- 每 1 秒输出一次位置信息
- 5秒后停止第1个定时器
之后来到
TimerInvokeType.cs
文件添加一下定时器的类型
csharp
namespace MH
{
public static class TimerInvokeType
{
//test
public const int TestTimer = 1;
public const int CoroutineTimeout = 1001;
//New TimeInvokeType
public const int MoveComponent_TimeInvokeType1 = 1002;
public const int MoveComponent_TimeInvokeType2 = 1003;
}
}
定义完定时器类型后修改
MoveComponent.cs
以及MoveComponentSystem.cs
csharp
using System;
namespace MH
{
public class MoveComponent : Entity, IAwake, IDestroy
{
public float X;
public float Y;
public float Z;
public long TimerId1;
public long TimerId2;
}
}
csharp
using System;
using UnityEngine;
namespace MH
{
[Invoke(TimerInvokeType.MoveComponent_TimeInvokeType1)]
public class MoveComponent_Timer1 : ATimer<MoveComponent>
{
protected override void Run(MoveComponent self)
{
Debug.Log($"Current: X:{self.X} Y:{self.Y} Z:{self.Z}");
}
}
[Invoke(TimerInvokeType.MoveComponent_TimeInvokeType2)]
public class MoveComponent_Timer2 : ATimer<MoveComponent>
{
protected override void Run(MoveComponent self)
{
self.Root.GetComponent<TimerComponent>().Remove(ref self.TimerId1);
Debug.Log("停止定时器1");
}
}
[EntitySystem]
public class MoveComponentAwakeSystem : AwakeSystem<MoveComponent>
{
protected override void Awake(MoveComponent self)
{
self.TimerId1 = self.Root.GetComponent<TimerComponent>().NewRepeatedTimer(
1000,
TimerInvokeType.MoveComponent_TimeInvokeType1,
self
);
self.TimerId2 = self.Root.GetComponent<TimerComponent>().NewOnceTimer(
TimeInfo.Instance.ClientNow() + 5000,
TimerInvokeType.MoveComponent_TimeInvokeType2,
self
);
}
}
[EntitySystem]
public class MoveComponentDestroySystem : DestroySystem<MoveComponent>
{
protected override void Destroy(MoveComponent self)
{
var timerComponent = self.Root.GetComponent<TimerComponent>();
timerComponent.Remove(ref self.TimerId1);
timerComponent.Remove(ref self.TimerId2);
}
}
public static class MoveComponentSystem
{
}
}
这时候来到MainInit_EventView
脚本中为Root添加MoveComponent
组件
csharp
namespace MH
{
[Event(SceneType.Main)]
public class MainInit_EventView : AEvent<Scene, Main_Init>
{
protected override async ETTask Run(Scene scene, Main_Init a)
{
//...
scene.AddComponent<MoveComponent>();
}
}
}
效果演示
效果视频
以下视频展示了定时器组件效果演示
技术支持
获取帮助
- 💬 加入QQ群讨论交流
(ET框架群)
: 474643097 - ⭐ 在GitHub上关注项目获取最新更新