>> >> >> Reference << << << <<<<<<Ref>>>>>>
>> >> >> Indexer << << << <<<<<<Idx>>>>>>
Matched: 0

Tags

    Categories

      Types

        Top Results

          FSM
          M: 2025-06-01 - ljf12825

          FSM(Finite State Machine,有限状态机)是一种常用的编程模型,广泛应用于游戏开发中,尤其是在行为控制、游戏角色AI、UI系统、动画控制方面

          它的核心就是在一组有限的状态中进行切换,且每次状态转移都遵循一定的规则

          基本概念

          FSM由以下几个基本元素构成:

          • 状态(State):系统当前的状态,表示系统的一种具体行为或情境
          • 状态转移(Transition):从一个状态到另一个状态的路径,通常基于某种条件或事件触发
          • 事件(Event):触发状态转移的条件或输入,通常由外部世界的变化或内部系统的某些操作引起
          • 动作(Action):状态进入、退出或在某个状态时发生的具体行为

          FSM的组成部分

          • 状态:状态机的每个状态都表示某一特定的系统情境。每个状态可能有自己的内部逻辑和行为。
          • 状态转移:从一个状态到另一个状态的过渡。转移通常由条件(如事件、输入、计时等)触发,状态机的核心就是处理这些条件,并做出相应的状态转换。
          • 事件与触发器:状态转移的条件。通常是由外部输入(如玩家输入、定时器超时、游戏中的其他事件)来触发。
          • 动作:当状态转移时会执行某些动作。比如,进入某个状态时播放动画,退出某个状态时停止某个动作等。

          FSM的工作流程

          FSM的工作过程可以概括为:每个时刻系统处于某个状态,系统等待某个事件的发生,一旦事件发生,就会根据事件的定义从当前状态转移到下一个状态,并可能触发某些动作。这个过程是循环的,状态机一直在不断地检查事件、进行状态转移。

          FSM示例:AI行为

          假设开发一个游戏中的敌人AI,敌人的行为可以通过FSM来管理,比如敌人有以下几个行为状态:

          • 巡逻(Patrolling):敌人沿着一个固定路径来回走
          • 追击(Chasing):敌人发现玩家并开始追逐
          • 攻击(Attacking):敌人接近玩家并进行攻击
          • 待机(Idle):敌人没有做任何事情,处于等待状态

          状态转移图:

          • 如果敌人没有发现玩家,状态保持在巡逻
          • 如果敌人发现玩家并进入追击状态,当玩家进入攻击范围时,切换到攻击状态
          • 如果玩家离开视野,回到巡逻状态
          • 如果敌人不再追击或攻击,返回待机状态

          每当敌人状态发生变化时,会有相应的动作,比如进入追击时播放追击动画,攻击时播放攻击动画

          FSM在Unity中的实现

          在Unity中,FSM通常通过脚本来实现。可以使用enum来定义状态,if条件判断或switch语句来管理状态转移,甚至用状态机设计模式来封装整个逻辑

          一个简单FSM实现

          public enum EnemyState
          {
              Patrolling,
              Chasing,
              Attacking,
              Idle
          }
          
          public class EnemyAI : MonoBehaviour
          {
              public EnemyState currentState;
              public Transform player;
              public float attackRange = 1.5f;
              public float chaseRange = 10f;
          
              private void Update()
              {
                  switch (currentState)
                  {
                      case EnemyState.Patrolling:
                          Patrolling();
                          break;
          
                      case EnemyState.Chasing:
                          Chasing();
                          break;
          
                      case EnemyState.Attacking:
                          Attacking();
                          break;
          
                      case EnemyState.Idle:
                          Idle();
                          break;
                  }
              }
          
              void Patrolling()
              {
                  // 巡逻逻辑
                  if (Vector3.Distance(transform.position, player.position) < chaseRange)
                  {
                      currentState = EnemyState.Chasing;
                  }
              }
          
              void Chasing()
              {
                  // 追击逻辑
                  if (Vector3.Distance (transform.position, player.position) < attackRange)
                  {
                      currentState = EnemyState.Attacking;
                  }
                  else if (Vector3.Distance (transform.position, player.position) > chaseRange)
                  {
                      currentState = EnemyState.Patrolling;
                  }
              }
          
              void Attacking()
              {
                  // 攻击逻辑
                  if (Vector3.Distance(transform.position - player.position, player.position) >= attackRange)
                  {
                      currentState = EnemyState.Attacking;
                  }
              }
          
              void Idle()
              {
                  // 待机逻辑
                  if (Vector3.Distance(transform.position, player.position) < chaseRange)
                  {
                      currentState = EnemyState.Chasing;
                  }
              }
          }
          

          解释:

          • 使用enum定义敌人的不同状态
          • switch语句用于根据当前状态执行不同的行为
          • 每个状态的方法中包含了触发状态转移的条件,例如距离检查、时间条件等

          FSM的优缺点

          优点:

          • 简单直观:FSM很容易理解,适合用于简单的状态管理
          • 易于维护:状态转移逻辑清晰,容易跟踪和调试
          • 灵活性高:可以轻松增加或修改状态,适应不同的需求

          缺点:

          • 状态保证:随着系统复杂度增加,状态和状态转移数量可能迅速增加,导致代码变得难以管理
          • 不适用于复杂逻辑:对于非常复杂的系统,FSM可能会变得笨重,维护困难

          优化与扩展

          • 层次状态机(Hierarchical FSM):可以在不同的状态中嵌套子状态机,使得系统结构更加清晰,适合复杂的AI行为
          • 事件驱动:通过事件驱动状态转移,可以避免大量的条件判断,提升代码的可维护性
          • 状态设计模式:可以将每个状态封装成独立的类,实现更为面向对象的设计,增加灵活性

          应用场景

          FSM不仅在游戏AI中有广泛应用,还可以在其他许多领域发挥作用,例如:

          • UI管理:不同的UI界面可以看作不同的状态,每个状态对应不同的UI布局和交互
          • 动画控制:可以根据角色的状态切换不同的动画,如走路、跑步、跳跃等
          • 玩家控制:玩家可以有不同的状态(走、跑、跳、攻击等),每个状态有不同的输入和动作