You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

游戏设计中敌人AI状态机:状态是否需自行评估转态逻辑?

敌人AI状态机的典型实现方案探讨

现有脚本结构

基础组件

  • Enemy
  • EnemyStateManager(状态机管理器)
  • EnemyStateBase(状态基类)

状态类

  • InitialState(初始状态)
  • RoamingState(巡逻状态)
  • PursuingState(追击状态)
  • AttackingState(攻击状态)
  • RetreatingState(撤退状态)

核心疑问

目前不确定应该将敌人的决策逻辑写在状态内部,还是用单独脚本调用当前状态的动作并由状态反馈动作可行性。比如在PursuingState中,敌人需要追逐目标直到进入攻击范围,当前的实现是在UpdateState方法中判断是否进入攻击范围,从而切换到AttackState。

当前实现代码示例

EnemyStateManager(状态机管理器)

public class StateMachine : MonoBehaviour {

    private EnemyStateBase _currentState;
    private Enemy _enemy;

    public Enemy Enemy { get => _enemy; set => _enemy = value; }


    private void Start() {
        _currentState = new RoamingState(this);
    }

    public void ChangeState(State newState) {
        _currentState.ExitState();
        _currentState = newState;
        _currentState.EnterState();
    }
    
    public void Update(){
        _currentState.UpdateState();
    }
}

PursuingState(追击状态)

public class PursuingState : EnemyStateBase {

    private EnemyStateManager _esm;

    public PursuingState (EnemyStateManager esm){
        _esm = esm;
    }
    
    public override void EnterState() {
        // 进入追击状态时执行的操作
    }

    public override void UpdateState() {
        // 检查是否进入目标的攻击范围
        var targetPos = _esm.Enemy.Target.Transform.Position;
        var myPos = _esm.Enemy.Transform.Position;

        if(Vector3.Distance(myPos, targetPos) < _esm.Enemy.AttackRange){
            _esm.ChangeState(new AttackState(_esm));
        }
    }

    public override void ExitState() {
        // 退出追击状态时执行的操作
    }
}

方案分析

你当前的实现方式属于AI状态机的典型方案,和玩家输入驱动的状态机(决策由外部输入触发)不同,AI状态机的核心逻辑就是让状态自身管理决策与状态切换——因为AI的行为逻辑是自主的,不需要外部输入来驱动。

这种将决策逻辑放在状态内部的方式有几个明显优势:

  • 职责单一:每个状态只需要关注自身的行为逻辑和切换条件,比如PursuingState只需要处理追击动作,以及判断何时切换到攻击状态,代码逻辑清晰,易于维护。
  • 内聚性强:状态相关的所有逻辑(进入、更新、退出、切换条件)都封装在同一个类中,避免了分散到多个脚本导致的逻辑混乱。
  • 扩展性好:后续新增状态时,只需要继承EnemyStateBase并实现自身的逻辑即可,不需要修改状态机管理器的核心代码,符合开闭原则。

如果采用“单独脚本调用状态动作+状态反馈可行性”的方式,反而会增加不必要的复杂度:需要额外维护一个决策脚本,还要处理状态与决策脚本之间的交互,反而违背了状态机模式封装状态逻辑的初衷。

当然,如果你后续遇到复杂的决策逻辑(比如多个状态共享的判断条件、全局状态切换规则),可以考虑将通用的判断逻辑抽离成工具类或者服务类,供各个状态调用,但核心的状态切换决策依然应该由状态自身来主导。

内容的提问来源于stack exchange,提问作者Katerlad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 06:30:03