状态机

本次完成的是一个基础状态机结构,主要用于管理玩家不同状态之间的切换,比如 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);

六、需要注意的问题

  1. Update() 里的 Debug.Log 会每帧打印,调试结束后最好删除或注释掉。

  2. Keyboard.current 最好加空值判断,避免特殊情况下空引用。

  3. ChangeState() 可以加判断,避免重复切换到当前状态:

if (currentState == newState)
  return;
  1. EntityState 中如果暂时不需要不带 Player 的构造函数,可以先删除,避免误用。

  2. 中文注释出现乱码,说明文件编码可能有问题,建议统一保存为 UTF-8。

七、核心理解

这个状态机的核心思想是:

Player 负责驱动
StateMachine 负责切换
EntityState 规定状态结构
具体State 负责具体逻辑

这样可以避免把所有逻辑都写在 Player.Update() 中,后续添加攻击、跳跃、受击等状态时会更清晰。

posted @ 2026-05-06 11:39  GhbBskl  阅读(14)  评论(0)    收藏  举报