これまで、私は有限状態マシンについて常に比較的抽象的に理解していました。いくつかのチュートリアルを読んだ後では、半分理解できたように感じます。個人的には、有限状態マシンを理解することはより抽象的であると感じています。
実際、有限ステート マシンは、Unity のアニメーターという比喩を通じてよく理解できます。
このような比喩を通して理解することは非常に鮮やかです。
首相はまず、3 つの抽象関数を含む BaseState を作成します。これは、各状態には開始と終了の 3 つの動作が必要であるためです。この BaseState は、インターフェイスまたは抽象クラスとして記述できます。後で使用するために状態に追加されます。抽象クラスに変更し、ここで抽象クラスを使用することをお勧めします。
//单个状态的基类 每个单独的基本状态都要继承这个类
//每个状态都有进入 保持 退出 三个状态
public abstract class BaseState
{
public abstract void Enter();
public abstract void Update();
public abstract void Exit();
}
すべての個々の状態はこの抽象クラスから継承する必要があり、BaseState は各状態の動作を指定します。
状態の切り替えを管理および制御するための FSM_Contronller スクリプトを作成する
public enum StateType
{
Idle,
Move,
Dead
}
//可以将FSM_Contronller喻为Unity中的Animator
public class FSM_Controller
{
//当前状态
private BaseState currentState;
//状态的类型
public StateType stateType;
//存储所有状态的容器
private Dictionary<StateType, BaseState> allSaveState;
public FSM_Controller()
{
//初始化容器
allSaveState = new Dictionary<StateType, BaseState>();
}
//保持当前状态
public void OnUpdate()
{
currentState?.Update();
}
public void AddState(StateType stateType, BaseState state)
{
//先判断状态容器中是否包含此态,重复状态不添加
if (allSaveState.ContainsKey(stateType))
return;
allSaveState.Add(stateType, state);
}
//状态切换
public void SetState(StateType stateType)
{
//如果当前状态和要跳转的状态相同 则不切换
if (currentState == allSaveState[stateType])
{
return;
}
//如果当前状态不为空 则退出当前状态
currentState?.Exit();
//将当前状态改为要跳转的状态
currentState = allSaveState[stateType];
//第一次进入状态 需要执行一次Enter
currentState.Enter();
}
}
コードの説明:
まず、現在の状態、状態タイプ、状態を保存するコンテナという 3 つの必要な変数が必要です。
ディクショナリを使用してすべての状態を格納します (1 対 1 のストレージ)。ディクショナリのキーは列挙された状態タイプで、値は BaseState を継承するすべての状態クラスです。ディクショナリ内の値は BaseState に直接置き換えられます。オブジェクト指向(Li変換原則)に準拠しています。
状態コンテナを初期化するにはコンストラクタが必要です
OnUpdate 関数が特定の状態に留まる
AddSatate 関数 コンテナに状態を追加するときは、最初に状態を判断する必要があります
SetState関数は状態を切り替えます
アイドル状態を例に挙げます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IdleState : BaseState
{
private Animator animator;
private FSM_Controller fsm;
private float stateCoolDown = 3f;
public IdleState(Animator animator, FSM_Controller fsm)
{
//如果有其他组件 如Animator 就在此一起初始化了
this.animator = animator;
this.fsm = fsm;
}
public override void Enter()
{
Debug.Log("进入Idle状态");
}
public override void Update()
{
Debug.Log("处于Idle状态");
stateCoolDown -= Time.deltaTime;
//过5秒切换状态
if (stateCoolDown <= 0)
{
fsm.SetState(StateType.Move);
}
}
public override void Exit()
{
Debug.Log("退出Idle状态");
}
}
BaseState を継承するには、状態の開始と終了、この状態での動作という 3 つの動作を実装する必要があります。
同時に、FSM_Contronller オブジェクトへの参照を含め、状態内の別の状態に切り替えるように初期化する必要があります。
Update Move で 3 秒後に状態を別の状態に切り替える