状态机模式(State Pattern)是一种行为设计模式,它允许一个对象在其内部状态改变时改变其行为,对象看起来好像修改了它的类。状态机模式在处理对象状态变化时特别有用,尤其是在游戏开发中,如AI行为、角色状态切换等。
下面我将详细说明如何在C#中实现一个通用的状态机模式,并举例应用在Unity中的游戏AI和动作序列。
### 实现通用状态机模式
首先,我们需要定义一个状态接口,该接口包括进入状态、更新状态和退出状态的方法。
- public interface IState
- {
- void Enter();
- void Execute();
- void Exit();
- }
然后,我们实现一个通用的状态机类,该类会管理当前的状态以及状态的切换。
- public class StateMachine
- {
- private IState currentState;
- public void ChangeState(IState newState)
- {
- if (currentState != null)
- {
- currentState.Exit();
- }
- currentState = newState;
- if (currentState != null)
- {
- currentState.Enter();
- }
- }
- public void Update()
- {
- if (currentState != null)
- {
- currentState.Execute();
- }
- }
- }
#### 1. 定义具体的状态
例如,我们有一个敌人角色,它有三种状态:巡逻(Patrol)、追击(Chase)和攻击(Attack)。 -
- public class PatrolState : IState
- {
- private EnemyAI enemyAI;
- public PatrolState(EnemyAI ai)
- {
- enemyAI = ai;
- }
- public void Enter()
- {
- Debug.Log("Entering Patrol State");
- // 设定巡逻起始
- }
- public void Execute()
- {
- Debug.Log("Patrolling...");
- // 巡逻逻辑
- if (enemyAI.CanSeePlayer())
- {
- enemyAI.StateMachine.ChangeState(new ChaseState(enemyAI));
- }
- }
- public void Exit()
- {
- Debug.Log("Exiting Patrol State");
- // 清理巡逻状态
- }
- }
- public class ChaseState : IState
- {
- private EnemyAI enemyAI;
- public ChaseState(EnemyAI ai)
- {
- enemyAI = ai;
- }
- public void Enter()
- {
- Debug.Log("Entering Chase State");
- // 设定追击开始
- }
- public void Execute()
- {
- Debug.Log("Chasing...");
- // 追击逻辑
- if (enemyAI.IsInRangeOfAttack())
- {
- enemyAI.StateMachine.ChangeState(new AttackState(enemyAI));
- }
- else if (!enemyAI.CanSeePlayer())
- {
- enemyAI.StateMachine.ChangeState(new PatrolState(enemyAI));
- }
- }
- public void Exit()
- {
- Debug.Log("Exiting Chase State");
- // 清理追击状态
- }
- }
- public class AttackState : IState
- {
- private EnemyAI enemyAI;
- public AttackState(EnemyAI ai)
- {
- enemyAI = ai;
- }
- public void Enter()
- {
- Debug.Log("Entering Attack State");
- // 设定攻击开始
- }
- public void Execute()
- {
- Debug.Log("Attacking...");
- // 攻击逻辑
- if (!enemyAI.IsInRangeOfAttack())
- {
- enemyAI.StateMachine.ChangeState(new ChaseState(enemyAI));
- }
- }
- public void Exit()
- {
- Debug.Log("Exiting Attack State");
- // 清理攻击状态
- }
- }
#### 2. 在敌人AI中使用状态机
定义敌人角色的AI控制脚本,并初始化状态机和初始状态。
- public class EnemyAI : MonoBehaviour
- {
- public StateMachine StateMachine { get; private set; }
- private void Start()
- {
- StateMachine = new StateMachine();
- StateMachine.ChangeState(new PatrolState(this));
- }
- private void Update()
- {
- StateMachine.Update();
- }
- public bool CanSeePlayer()
- {
- // 检测玩家是否在视野范围内
- return false;
- }
- public bool IsInRangeOfAttack()
- {
- // 检测玩家是否在攻击范围内
- return false;
- }
- }
述实现展示了如何使用状态机模式来组织游戏AI的行为,通过将复杂的行为逻辑分解成不同的状态类,并使用状态机来管理和调度这些状态,可以显著简化代码,使得系统更具扩展性和可维护性。