状态机
本次完成的是一个基础状态机结构,主要用于管理玩家不同状态之间的切换,比如 Idle 和 Move。
一、整体结构
当前状态机主要由四部分组成:
- Player:玩家本体,负责创建状态机和各个状态
- StateMachine:状态机核心,负责保存当前状态和切换状态
- EntityState:状态基类,定义所有状态共有的方法
- Player_IdleState / Player_MoveState:具体状态类,负责各自状态下的逻辑
二、状态生命周期
每个状态都有三个核心方法:
Enter() Update() Exit() 含义分别是:
- Enter():进入状态时调用一次
- Update():处于当前状态时每帧调用
- Exit():离开状态时调用一次
状态切换流程是:
旧状态 Exit() 切换 currentState 新状态 Enter() 三、Player 的作用
Player 中创建状态机和状态对象:
stateMachine = new StateMachine(); idleState = new Player_IdleState(this, stateMachine, "Idle"); moveState = new Player_MoveState(this, stateMachine, "Move"); 然后设置初始状态:
stateMachine.Initialize(idleState); 每帧执行当前状态的逻辑:
stateMachine.currentState.Update(); 所以 Player 本身不直接处理所有状态逻辑,而是把逻辑交给当前状态。
四、StateMachine 的作用
StateMachine 保存当前状态:
public EntityState currentState { get; private set; } 初始化状态:
currentState = startState; currentState.Enter(); 切换状态:
currentState.Exit(); currentState = newState; currentState.Enter(); 它只负责状态管理,不处理具体角色行为。
五、具体状态逻辑
Player_IdleState 表示待机状态。
当前测试逻辑是:按下 F 切换到移动状态。
stateMachine.ChangeState(player.moveState); Player_MoveState 表示移动状态。
当前测试逻辑是:按下 G 切换回待机状态。
stateMachine.ChangeState(player.idleState); 六、需要注意的问题
-
Update() 里的 Debug.Log 会每帧打印,调试结束后最好删除或注释掉。
-
Keyboard.current 最好加空值判断,避免特殊情况下空引用。
-
ChangeState() 可以加判断,避免重复切换到当前状态:
if (currentState == newState) return; -
EntityState 中如果暂时不需要不带 Player 的构造函数,可以先删除,避免误用。
-
中文注释出现乱码,说明文件编码可能有问题,建议统一保存为 UTF-8。
七、核心理解
这个状态机的核心思想是:
Player 负责驱动 StateMachine 负责切换 EntityState 规定状态结构 具体State 负责具体逻辑这样可以避免把所有逻辑都写在 Player.Update() 中,后续添加攻击、跳跃、受击等状态时会更清晰。
浙公网安备 33010602011771号