FSM
Unity にはすでにアニメーション ステート マシンがありますが、オープン コードとクローズド コードの原則のため、現時点では FSM 有限ステート マシンの役割が強調されています。
有限状態マシンを制御するスクリプトを作成する
まず、主に状態を切り替えるために、有限状態マシン (FSM) を制御するスクリプトを作成します。
まず列挙を使用して各状態をリストします。
public enum StateType
{
ldle,
run,
jumping,
dying,
shooting
}
次に、現在の状態を保存し、その後の次の状態への変更を容易にするために辞書に保存するためのコンテナが必要です。その後、クラスを初期化し、辞書を作成し、状態を増加および設定するための 2 つのメソッドを追加し、最後にそれを毎回実行します。フレーム。コードは以下のように表示されます
//当前在运行什么状态
private State currentState;
public StateType stateType;//各个状态的标识符
//写一个保存所有状态的容器
private Dictionary<StateType, State> allSaveState;
public FSMControl()
{
allSaveState = new Dictionary<StateType, State>();
}
public void OnTick()//每一帧执行一次
{
currentState?.OnUpdate();
}
public void AddState(StateType stateType, State state)
{
if (allSaveState.ContainsKey(stateType))
return;
allSaveState.Add(stateType, state);
}
public void SetState(StateType stateType)//我们需要传一个参数,告诉状态机需要切换到哪一个状态中去
{
if (currentState == allSaveState[stateType]) return;//判断当前状态是否重复
currentState?.OnEnter();//判断当前状态是否为空
currentState = allSaveState[stateType];
currentState.OnEnter();
}
完全なコードは次のとおりです
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum StateType
{
ldle,
run,
jumping,
dying,
shooting
}
public class FSMControl
{
//当前在运行什么状态
private State currentState;
public StateType stateType;//各个状态的标识符
//写一个保存所有状态的容器
private Dictionary<StateType, State> allSaveState;
public FSMControl()
{
allSaveState = new Dictionary<StateType, State>();
}
public void OnTick()//每一帧执行一次
{
currentState?.OnUpdate();
}
public void AddState(StateType stateType, State state)
{
if (allSaveState.ContainsKey(stateType))
return;
allSaveState.Add(stateType, state);
}
public void SetState(StateType stateType)//我们需要传一个参数,告诉状态机需要切换到哪一个状态中去
{
if (currentState == allSaveState[stateType]) return;//判断当前状态是否重复
currentState?.OnEnter();//判断当前状态是否为空
currentState = allSaveState[stateType];
currentState.OnEnter();
}
}
FSM ステート マシンで各状態を設定します
次に、状態の 1 つが示され、他の状態も同様に記述できます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ldle: State
{
private Animator animator;
private float deltaTime = 5f;
private FSMControl fsm;
public ldle(Animator animator,FSMControl fsm)
{
this.animator = animator;
this.fsm = fsm;
}
//刚刚进入状态时的行为
public override void OnEnter()
{
Debug.Log("闲");
}
//正在进行状态时的行为
public override void OnUpdate()
{
Debug.Log("站着吧");
if (deltaTime >= 0)
{
deltaTime -= Time.deltaTime;
if (deltaTime<0)
{
fsm.SetState((StateType.run));//更改状态为跑
}
}
}
//退出状态后的行为
public override void OnExit()
{
Debug.Log("该动起来了");
}
}
状態の切り替え条件は自分の状況に合わせて変更できますが、ここでは5秒後に実行する状態に設定しています。
テストクラスを追加する
ただし、最初の 2 つのスクリプトを書き終えた後は、テスト クラスを追加できます。つまり、さまざまな状態を追加して初期状態を設定した後、通常どおり実行できるようになります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestFSM : MonoBehaviour
{
private FSMControl fsm;
private StateType stateType;
private Animator animator;
private void Awake()
{
fsm = new FSMControl();
animator = GetComponentInChildren<Animator>();
fsm.AddState(StateType.ldle, new ldle(animator,this.fsm));
fsm.AddState(StateType.run, new run(animator));
fsm.SetState(StateType.ldle);
}
private void Update()
{
fsm.OnTick();
}
}
FSM の利点
新しい状態が必要な場合は、FSMControl を継承するようにスクリプトを直接設定できます。これにより、オープン コードとクローズド コードの原則が保証されます。アニメーション ステート マシン スイッチを使用する場合は、元のコードを直接変更する必要があります。FSM を使用すると、次のことができます。新しいスクリプトを直接作成して増加を実現します。