在实际的游戏开发中,角色行为和UI逻辑往往会随着需求的增加变得复杂。一个角色可能需要在“待机”“移动”“攻击”“受伤”等状态之间切换,而UI则可能在“主界面”“战斗界面”“结算界面”等界面之间切换。
如果没有合适的架构,逻辑很容易写成一大堆 if-else 或 switch-case ,不仅难以维护,还容易出错。
这时,状态机(State Machine) 就成为一个理想的解决方案。
什么是状态机?
状态机(State Machine)是一种用于管理对象在不同“状态”之间切换的设计模式。它的核心思想是:
-
每个状态独立负责一部分逻辑 (例如角色攻击状态 vs. 移动状态);
-
状态之间有明确的切换规则 (例如攻击动画播放完毕 → 回到待机状态);
-
避免臃肿的条件判断 ,提升代码可读性与可维护性。
简单来说,状态机的作用就是 让逻辑模块化,切换有序化 。
案例:角色状态切换
假设我们有一个角色,需要管理以下状态:
-
Idle(待机)
-
Move(移动)
-
Attack(攻击)
如果直接写在 Update() 里,代码可能是这样的:
void Update() {
if (isAttacking) {
// 攻击逻辑
}
else if (isMoving) {
// 移动逻辑
}
else {
// 待机逻辑
}
}
随着需求增加,判断会越来越多,最终难以维护。
使用状态机后,我们可以把逻辑分散到独立的状态类中:
// 状态接口
public interface IState {
void Enter();
void Update();
void Exit();
}
// 待机状态
public class IdleState : IState {
public void Enter() => Debug.Log("进入待机");
public void Update() {
/* 待机逻辑 */
}
public void Exit() => Debug.Log("离开待机");
}
// 攻击状态
public class AttackState : IState {
public void Enter() => Debug.Log("进入攻击");
public void Update() {
/* 攻击逻辑 */
}
public void Exit() => Debug.Log("离开攻击");
}
状态机管理器只需要维护当前状态:
public class StateMachine {
private IState currentState;
public void ChangeState(IState newState) {
currentState?.Exit();
currentState = newState;
currentState.Enter();
}
public void Update() {
currentState?.Update();
}
}
在角色逻辑中使用:
public class Character : MonoBehaviour {
private StateMachine stateMachine = new StateMachine();
void Start() {
stateMachine.ChangeState(new IdleState());
}
void Update() {
stateMachine.Update();
if (Input.GetKeyDown(KeyCode.Space)) {
stateMachine.ChangeState(new AttackState());
}
}
}
这样,角色的每个状态都被封装在独立类中,逻辑清晰、可扩展性强。
状态机不仅能用于角色,也非常适合 UI 管理 。
例如:
主界面 → 战斗界面 → 结算界面
用状态机切换界面时,可以统一管理“进入界面时做什么”“离开界面时做什么”。
避免 UI 代码到处都是 SetActive(true/false) 的混乱情况。
总结
使用状态机需要注意的几点
-
避免状态过度细分
如果状态划分过细,会让系统显得复杂。通常一个“行为大类”才需要一个状态。
-
状态切换要明确
每个状态的切换条件要清晰,否则可能出现逻辑死循环或状态卡死。
-
结合事件或动画回调
在实际项目中,状态切换往往要与动画事件或 UI 按钮绑定,确保切换及时、自然。
状态机为复杂逻辑提供了 模块化、清晰化 的解决方案。掌握状态机后,你会发现逻辑切换不再混乱,而是井然有序。
-
它能避免臃肿的条件判断;
-
提高代码的可读性和扩展性;
-
在角色行为、UI 切换等场景下非常适用。
