FSM_基本的有限状态机的实现

在此之前,一直对有限状态机有一个比较抽象的理解,看过好几个教程,似懂非懂的感觉,直接上手代码个人觉得是比较吃抽象的理解起来有限状态机
其实通过一个比喻就可以很好的理解有限状态机了,就是Unity中的Animator
通过这样的比喻理解 就很形象了 

 首相先创建一个BaseState,包含三个抽象函数,因为每个状态都要有 进入 处于 退出 三个行为,将这个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();
    }

}

代码解释:

首先需要三个必要的变量 当前状态 状态类型 存储状态的容器

用字典存储所有的状态,一对一进行存储,字典中的键就为枚举的状态类型,值就为继承了BaseState的所有状态类,字典中的值用BaseState直接替代,符合面向对象(里氏转换原则)

需要有个构造函数 初始化状态容器 

OnUpdate函数 保持处于某个状态

AddSatate函数  添加状态到容器中去 添加的时候要先进行判断

SetState函数 切换状态 

以Idle State为例:

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 都必须实现三个行为 进入状态 处于 退出 在这个状态分别要做什么 

扫描二维码关注公众号,回复: 16106195 查看本文章

同时得包含FSM_Contronller对象的引用 以及初始化 便于在状态内切换到另一个状态

在Update中 三秒后切换状态到另一个状态Move 

猜你喜欢

转载自blog.csdn.net/m0_69778537/article/details/132093632