Unity协程计时器
Unity协程计时器详解:理解 ResetComboAfterTimeout 的工作原理
在我的代码中,协程计时器(主要是 ResetComboAfterTimeout)用于管理攻击连招的超时重置机制。本文将详细解析这部分代码的工作原理、目的和实现方式。
协程基础
首先,让我们理解一下 Unity 协程的基本概念:
- 协程:一种可以暂停执行并在之后恢复的函数。
yield语句:用于暂停和恢复协程。- 协程可以在不阻塞主线程的情况下等待特定的时间或条件。
- 协程可以通过
StartCoroutine启动,通过StopCoroutine停止。
代码中的协程计时器实现
1. 主要变量
1 | private float _comboResetTime = 2f; // 超时重置时间 |
2. 协程启动时机
在您的代码中,协程在攻击冷却结束后启动:
1 | TimeManger.MainInstance.TryGetOneTimer(_MaxColdTime, () => |
3. 协程的实现
1 | private IEnumerator ResetComboAfterTimeout() |
4. 协程的取消时机
当玩家继续输入攻击时,协程会被取消:
1 | if (CanCharaBaseAttack() && GameInputManger.Instance.LAttack) |
工作流程详解
让我们完整梳理一下连击系统和协程计时器的工作流程:
1. 玩家发起第一次攻击
当玩家按下攻击按钮,触发 ExecuteComboAttack():
- 播放攻击动画
- 设置冷却时间
- 禁用攻击输入(
_CanInputAttack = false) - 通过
TimeManger启动冷却计时器
2. 攻击冷却结束
当攻击冷却结束,TimeManger 回调执行:
- 重新启用攻击输入(
_CanInputAttack = true) - 启动协程计时器
ResetComboAfterTimeout()(关键步骤)
3. 玩家有两种选择
选择 A:在超时前继续攻击
1 | 玩家攻击 → 冷却结束 → 启动协程 → [玩家迅速输入] → 取消协程 → 执行下一招 → ... |
当玩家在 _comboResetTime(2秒)内继续攻击:
- 检测到
GameInputManger.Instance.LAttack为true - 取消当前的协程计时器(
StopCoroutine(_resetCoroutine)) - 执行下一个连击动作
- 增加
CurrentComboIndex - 重新开始冷却 → 协程循环
选择 B:超时不攻击
1 | 玩家攻击 → 冷却结束 → 启动协程 → [玩家没有输入] → 协程完成等待 → 重置连击索引 |
当玩家在 _comboResetTime(2秒)内没有继续攻击:
- 协程完成等待
WaitForSeconds(_comboResetTime) - 执行
CurrentComboIndex = 0,重置连击索引 - 玩家再次攻击时将从第一招开始
图解
1 | ┌─────────┐ 按攻击键 ┌───────────────┐ |
代码分析的关键部分
1. 协程的存储与引用
1 | private Coroutine _resetCoroutine; |
该变量存储了对正在运行的协程的引用,使得您可以:
- 检查协程是否正在运行(
_resetCoroutine != null) - 在需要时停止协程(
StopCoroutine(_resetCoroutine))
2. 协程的启动
1 | _resetCoroutine = StartCoroutine(ResetComboAfterTimeout()); |
StartCoroutine 方法返回一个 Coroutine 对象,它被存储在 _resetCoroutine 中。
3. 协程的取消
1 | if (_resetCoroutine != null) |
当需要取消协程时,使用 StopCoroutine 并将引用设为 null。
4. 协程完成后的自清理
1 | private IEnumerator ResetComboAfterTimeout() |
协程完成任务后,会自清理自己的引用,表示协程已经结束。
这种设计的好处
- 不阻塞游戏主线程:使用协程而不是传统的计时器可以避免阻塞主线程,保持游戏流畅性。
- 易于取消:可以根据玩家的输入立即取消计时器,灵活控制连击。
- 代码清晰:使用协程处理延时任务比回调函数更加直观。
- 内存效率:协程结束后会被垃圾回收,避免内存泄漏。
改进建议
虽然实现已经很好,但可以考虑以下改进:
1. 添加更多状态检查
1 | private IEnumerator ResetComboAfterTimeout() |
2. 考虑使用可取消令牌
1 | private CancellationTokenSource _resetTokenSource; |
总结
在您的连击系统中,协程计时器用于实现以下功能:
- 连击超时重置:当玩家在指定时间内(
_comboResetTime)没有继续攻击,系统会自动重置连击索引。 - 灵活的取消机制:当玩家继续输入攻击时,计时器会被取消,允许连击继续。
- 清晰的状态管理:无论计时器是被取消还是自然完成,都会清理自己的引用,避免内存泄漏。
这种机制是动作游戏中实现连击系统的常用方法,它允许玩家在一定时间窗口内继续连击,但不会无限期地保持连击状态,符合大多数动作游戏的设计习惯。
协程计时器是 Unity 中处理这类“延迟执行且可能需要取消”的任务的优雅解决方案。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 砂糖·橘🍊!
