Implementation of FSM_basic finite state machine

Before this, I have always had a relatively abstract understanding of finite state machines. After reading several tutorials, I feel half-understood. I personally feel that it is more abstract to understand finite state machines.
In fact, the finite state machine can be well understood through a metaphor, which is the Animator in Unity
It is very vivid to understand through such a metaphor. 

 The Prime Minister first creates a BaseState, which contains three abstract functions, because each state must have three behaviors of entering and exiting. This BaseState can be written as an interface or an abstract class. If there are non-abstract members that need to be added to the state for subsequent use, It is recommended to change to an abstract class, and use an abstract class here
//单个状态的基类 每个单独的基本状态都要继承这个类
//每个状态都有进入 保持 退出 三个状态
public abstract class BaseState
{
    public abstract void Enter();
    public abstract void Update();
    public abstract void Exit();
}

All individual states must inherit from this abstract class, where BaseState specifies the behavior of each state

 Create a FSM_Contronller script to manage and control state switching

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();
    }

}

Code explanation:

First of all, three necessary variables are required for the current state state type to store the state container

Use a dictionary to store all states, one-to-one storage, the key in the dictionary is the enumerated state type, and the value is all the state classes that inherit BaseState. The value in the dictionary is directly replaced by BaseState, which is in line with object-oriented (Li conversion principle)

Requires a constructor to initialize the state container 

The OnUpdate function stays in a certain state

AddSatate function When adding a state to a container, it must be judged first

The SetState function switches the state 

Take Idle State as an example:

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状态");
    }


}

Inheriting BaseState must implement three behaviors, enter the state and exit, and what to do in this state 

At the same time, it must contain a reference to the FSM_Contronller object and initialize it to switch to another state within the state

Switch state to another state after three seconds in Update Move 

Guess you like

Origin blog.csdn.net/m0_69778537/article/details/132093632