Unity C#使用Action实现定时触发游戏事件的逻辑是否正确?
逻辑可行性结论
你的实现思路是可行的,核心逻辑「通过Action聚合多个回调,定时检查时间符合条件后统一触发」完全可以满足指定时间点触发a、b、c三个事件的需求,不过存在几个可优化和需要修正的细节:
问题修正与优化建议
1. Action泛型参数的选择
Action<T>是C#内置的泛型委托,尖括号里的类型代表委托调用时需要传入的参数类型,你看到的Action<int>只是示例场景需要传入int参数,并不是固定要求:
- 如果你要触发的a、b、c三个事件不需要接收任何参数,直接用无参的
Action即可,把声明改成:
// 无参委托,不需要加尖括号和int public static Action morningEvents = delegate { };
- 如果你需要把和当前触发场景相关的信息(比如当前时间戳、当日周数等)传递给回调事件,才需要指定对应的泛型参数,比如需要传递当前是周几,就可以定义为
Action<int>,调用时传入对应参数:
// 触发时传入周几的数值 morningEvents?.Invoke((int)DateTime.Now.DayOfWeek); // 注册的回调方法也要对应接收int参数 void EventA(int dayOfWeek) { // 内部可根据周数做差异化逻辑 }
2. 避免同一事件重复触发
如果你的CheckTime方法是每秒/每帧轮询执行,要加触发标记避免10点整的检查周期内重复触发事件,参考实现:
// 标记当日10点事件是否已经触发过 private bool _morningEventsTriggeredToday = false; void CheckTime() { var currentTime = DateTime.Now; // 匹配到10点整且当日未触发过才执行 if (currentTime.Hour == 10 && currentTime.Minute == 0 && currentTime.Second == 0) { if (!_morningEventsTriggeredToday) { // 用?.Invoke 避免委托为空时报错,比直接调用更安全 morningEvents?.Invoke(); _morningEventsTriggeredToday = true; } } // 过了10点后重置标记,保证第二天可以正常触发 else if (currentTime.Hour > 10) { _morningEventsTriggeredToday = false; } }
3. 委托安全性优化
建议给公共委托加上event关键字,避免外部代码直接将委托置空清空所有注册的回调:
// 加event关键字后,外部只能用+=/-=注册/注销回调,不能直接修改整个委托对象 public static event Action morningEvents = delegate { };
内容的提问来源于stack exchange,提问作者DataLearner555
相关产品推荐
相关产品推荐

