资讯动态

HFSM 子状态机与历史状态恢复:战斗被打断后的无缝恢复

发布时间:2026/9/17 8:21:38 来源:尧图企业网站定制
HFSM 子状态机与历史状态恢复战斗被打断后的无缝恢复在动作游戏与深度 RPG 的 NPC AI 开发中最令策划与程序员抓狂的体验之一莫过于“AI 的断点失忆”。设想一个典型战斗场景Boss 正在执行一个由三段连招构成的复合战术起手蓄力 $\rightarrow$ 突进斩击 $\rightarrow$ 地面重锤震波当前进行到第二段突进中途。此时玩家使用强控技能如击晕、冰冻或击退破招打断了 Boss。Boss 切换进入“受击硬直Stunned”状态。两秒后硬直结束如果状态机直接粗暴地回退到顶层的“空闲Idle”或重置到连招第一段Boss 就会显得极其机械、迟钝而如果状态机丢失了先前的战术目标甚至可能在玩家眼前原地发呆。分层有限状态机Hierarchical Finite State MachineHFSM通过引入子状态机Sub-State Machine与历史状态恢复机制History State / Deep History优雅地解决了多层级复合行为在遭遇突发中断时的断点保护与平滑衔接问题。扁平 FSM 与 HFSM 的历史机制差异传统的扁平状态机在处理中断时必须在每一个可能被打断的状态与所有中断状态之间建立网状连线$O(N^2)$ 的复杂度。而在 HFSM 中父状态聚合Combat是一个宏观父状态其内部包含ComboSequence连招子状态机、TacticalRetreat战术后撤等子状态。高层级抢占中断当全局事件如StunReceived触发时直接在顶层状态机发生状态跃迁Combat$\rightarrow$CrowdControlled。浅层历史Shallow History, $H$当离开复合状态时记录其最近激活的直接子状态。重返该状态时直接激活该子状态。深层历史Deep History, $H^*$不仅记录直接子状态还递归记录所有嵌套孙代子状态机的内部激活节点与局部执行进度如技能前摇帧数、冷却时间进度。┌─────────────────────────────────────────────────────────┐ │ Combat (父状态) │ │ │ │ ┌───[H* 历史恢复标记] │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ ComboSequence (连招子状态机) │ │ │ │ │ │ │ │ [Phase1: 蓄力] ──► [Phase2: 突进] ──► [Phase3: 重锤]│ │ │ └──────────────────────────┬──────────────────────────┘ │ └────────────────────────────┼────────────────────────────┘ │ 受到眩晕中断 │ 控制结束重返 (H*) ▼ ┌─────────────────────────────────────────────────────────┐ │ CrowdControlled (受控硬直状态: 倒地 / 击晕) │ └─────────────────────────────────────────────────────────┘HFSM 深度历史状态机核心实现下面是一套在 C# 客户端引擎中经过工业级验证的轻量 HFSM 核心框架支持强类型状态定义与 Deep History 现场保存using System; using System.Collections.Generic; public abstract class HFSMState { public string Name { get; } public HFSMState Parent { get; set; } protected HFSMState(string name) { Name name; } public virtual void OnEnter() { } public virtual void OnUpdate(float deltaTime) { } public virtual void OnExit() { } } public class HFSMHierarchicalState : HFSMState { private readonly Dictionarystring, HFSMState _subStates new Dictionarystring, HFSMState(); private HFSMState _currentState; private HFSMState _defaultSubState; private HFSMState _historyState; // 记录离开时的历史状态 public bool UseDeepHistory { get; set; } true; public HFSMHierarchicalState(string name) : base(name) { } public void AddSubState(HFSMState state, bool isDefault false) { state.Parent this; _subStates[state.Name] state; if (isDefault) { _defaultSubState state; } } public void TransitionTo(string stateName) { if (!_subStates.TryGetValue(stateName, out var nextState)) return; _currentState?.OnExit(); _currentState nextState; _currentState.OnEnter(); } public override void OnEnter() { base.OnEnter(); // 优先根据历史状态恢复现场若无历史则进入默认初始状态 if (UseDeepHistory _historyState ! null) { _currentState _historyState; } else { _currentState _defaultSubState; } _currentState?.OnEnter(); } public override void OnUpdate(float deltaTime) { base.OnUpdate(deltaTime); _currentState?.OnUpdate(deltaTime); } public override void OnExit() { // 退出复合父状态时将当前正在运行的子节点保存到历史快照 _historyState _currentState; _currentState?.OnExit(); base.OnExit(); } public void ClearHistory() { _historyState null; if (_currentState is HFSMHierarchicalState childHierarchical) { childHierarchical.ClearHistory(); } } }实战中的动作打断与补偿策略在真实的 Boss 战斗中单纯恢复状态机节点还不够必须配合动画系统与位移插值补偿被打断动作的超时失效State Expiration Window历史状态不能无限期有效。如果 Boss 被连续击晕了整整 10 秒醒来后再继续打完 10 秒前蓄力的突进斩击就会显得非常诡异。解决方案为历史快照记录时间戳HistorySavedTime。当Time.time - HistorySavedTime MaxResumeThreshold例如 2.5 秒强制清空历史唤醒后重置为普通站立或警觉挑衅动作。后摇中断与前摇中断的分流处理若技能处于前摇蓄力阶段被打断恢复后应当重新从蓄力第 0 帧开始播放或直接取消该技能进入 CD若技能处于攻击判定生效后摇阶段被打断说明伤害已经结算恢复后直接跳过判定帧平滑混合进收招动作。动画 CrossFade 容错保护从CrowdControlled返回ComboSequence时动画控制器不能直接 Snap 到历史帧而必须调用animator.CrossFade(targetClip, 0.15f)进行姿态平滑混合避免角色模型出现瞬移和四肢撕裂。通过层次状态机的结构化抽象与深层历史恢复AI 拥有了对抗复杂战斗打断的记忆能力既保持了宏观行为的战略连贯性又具备了微观物理交互的拟真质感。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价