FSM状态机的学习与实现
最近,学习了一下FSM状态机,觉得挺有意思的.
百科上得来的解释为:有限状态机,(英语:Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
FSMState: FSM状态机状态基类(自定义状态所需要继承的基类)
FSMTag: FSM状态机状态键(FSMSystem所维护的键值对列表中对应状态的键值列表)
FSMSystem: FSM状态机系统(状态机控制类-基类)
FSMController: FSM状态机控制(状态机控制类-子类-游戏对象挂载)
FSMTag: 存储状态切换时所用的常量字符串
FSMSystem: 维护状态列表,实现对状态的管理.
FSMState: 修改脚本实现状态的执行效果(可复写进入状态,退出状态,保持状态,退出条件)
FSMController: 挂载游戏对象上,实现状态机效果,继承自FSMSystem(可复写FSMInit,FSMUpdate,FSMFixedUpdate)
FSMState状态基类的实现代码:
/// <summary>
/// 抽象状态类,作为自定义状态的基类,继承使用
/// </summary>
public abstract class FSMState
{protected bool onState;//针对是否是初次进入该状态,实现OnEnter函数用/// <summary>/// 状态构造函数/// </summary>/// <param name="StateKeyName">状态键</param>/// <param name="fsm">状态</param>public FSMState(string StateKeyName, FSMSystem fsm){fsm.AddState(StateKeyName, this);}/// <summary>/// 退出条件/// </summary>/// <returns></returns>public abstract string ExitCondition(Transform player, Transform npc);/// <summary>/// 进入状态前/// </summary>public virtual void OnEnter(Transform player, Transform npc) { onState = true; }/// <summary>/// 退出状态时/// </summary>public virtual void OnExit(Transform player, Transform npc) { onState = false; }/// <summary>/// 状态停留时/// </summary>public abstract void OnStay(Transform player, Transform npc);/// <summary>/// 管理状态的切换行为逻辑/// </summary>/// <param name="target"></param>public virtual void OnState(Transform player, Transform npc){if (!onState)//检查是否执行初次进入状态OnEnter(player,npc);else //如果不是初次进入状态OnStay(player,npc);}
}
该脚本拥有三个复写状态函数(状态触发时,状态退出时,状态停留时),其中停留状态为抽象函数,必须重写
该脚本拥有两个逻辑执行函数(ExitCondition负责状态退出条件条件的判断,返回状态键,用以切换状态,OnState负责管理状态函数的执行逻辑,前者抽象,必须实现,后者可忽略)
FSMSystem状态管理类的实现代码:
/// <summary>
/// FSM系统类(FSM状态管理类)
/// </summary>
public class FSMSystem : MonoBehaviour
{public Dictionary<string, FSMState> map;//状态列表public Transform target;//目标对象public FSMState currentValue;//活动状态public string currentKey;//活动键protected virtual void FSMInit() { }//FSM初始化protected virtual void FSMFixedUpdate() { }//FSM物理刷新protected virtual void FSMUpdate(){currentKey = currentValue.ExitCondition(transform, target);//检查退出条件是否满足if (currentKey != null)//满足切换状态条件{currentValue.OnExit(transform, target);//如果满足,则执行退出函数currentValue = map[currentKey];//获取新的活动状态}else currentValue.OnState(transform, target);//如果退出条件不满足,则执行状态}//FSM刷新运行管理机制实现/// <summary>/// 添加状态/// </summary>/// <param name="index"></param>/// <param name="s"></param>public void AddState(string stateName, FSMState s){if (!map.ContainsKey(stateName)) map.Add(stateName, s);}/// <summary>/// 删除状态/// </summary>/// <param name="index"></param>public void DeleteState(string stateName){if (map.ContainsKey(stateName)) map.Remove(stateName);}/// <summary>/// 开始函数,在FSMInit函数执行后,将状态集合的第一个状态设置为默认状态/// </summary>void Start(){map = new Dictionary<string, FSMState>();//持有状态列表FSMInit();//初始化信息currentKey = map.FirstOrDefault().Key;currentValue = map.FirstOrDefault().Value;}/// <summary>/// 刷新/// </summary>void Update(){FSMUpdate();}/// <summary>/// 物理刷新/// </summary>private void FixedUpdate(){FSMFixedUpdate();}
}
该脚本有一个键值对集合,用以储存状态列表,采用的键为string,前面FSMState脚本内退出条件函数的返回值为同类型,在FSMUpdate函数内配合实现状态切换逻辑
所有状态函数的添加需要在FSMInit函数内实现(在FSMController中进行)
该脚本有FSMInit,FSMUpdate,FSMFixedUpdate三个生命周期函数,所有与FSM相关逻辑可以放入其中实现
FSMController状态控制类的实现代码:
/// <summary>
/// FSM状态控制类,挂载对象上使用,仅需要复写FSMInit函数,进行状态的添加即可
/// </summary>
public class FSMController : FSMSystem {public List<Transform> paths;//巡逻路径protected override void FSMInit(){//创建角色状态new Idle(FSMTag.Idle,this);//闲置状态添加new Patrol(FSMTag.Patrol,this);//巡逻状态添加new Chase(FSMTag.Chase, this);//追逐状态添加new Attack(FSMTag.Attack, this);//攻击状态添加}
}
该脚本内FSMInit函数负责FSM状态机状态的初始化操作,所有自定义状态均需要在其中进行添加,仅需要new状态函数即可
该脚本内new的状态均为继承自FSMState实现,构造函数所需要传入的参数实际上就是状态的键和当前脚本对象
之所以传入当前脚本对象,是因为该脚本继承自FSMSystem,这里起到在状态构造函数中自动添加该状态到FSMSystem维护列表中去,起到简化操作的作用
FSMTag状态键常量类的实现代码:
/// <summary>
/// FSM状态常量类
/// </summary>
public class FSMTag
{public const string Idle = "Idle";public const string Patrol= "Patrol";public const string Chase = "Chase";public const string Attack = "Attack";
}
最后一个类,负责FSMSystem中状态列表切换使用的状态键的存储,之所以有这个类,纯粹是为了方便状态键的修改
最后,放上Demo下载链接:https://download.csdn.net/download/u012636407/10512630
FSM状态机的学习与实现相关推荐
- Godot3游戏引擎入门之十四:RigidBody2D刚体节点的应用以及简单的FSM状态机介绍
一.前言 时间飞逝,距离上次更新已经有半年之久!这几个月里我只有三分之一的时间很忙,相反其他时间是比较闲的,但是由于空闲时间非常"碎片化",导致我一直没有集中精力搞自己喜欢的&qu ...
- 序列检测(FSM状态机)
序列产生和检测(FSM状态机) 提示:FSM有限状态机,是FPGA和数字IC相关岗位必须要掌握的知识点,在笔试和面试中都非常常见. 文章目录 序列产生和检测(FSM状态机) 前言 一.状态机基本概念 ...
- simple fsm状态机模板应用笔记(二)——simple fsm语法规则
原文地址:https://www.amobbs.com/thread-5668532-1-1.html 如何使用 1. 如何定义一个状态机 语法: simple_fsm( <状态机名称>, ...
- FSM状态机之状态模式
首先声明一点,这个模式是我目前见过最好用(本人观点),但是也是最难理解的一个(本人观点). 所以大家需要做好心理准备,如果,对这个模式没有特别强烈的需求,比如: 我有一个Button,我按次数点击它 ...
- 源码 状态机_LLVM学习笔记(1)--初探源码
一直耳闻LLVM相比于GCC: well documented 架构灵活,前后端解耦符合龙书的讲解 昨天读到了一篇虽然概括却很周到的llvm入门导引 陈钦霖:LLVM Pass入门导引zhuanla ...
- 三段式状态机_FPGA笔试题——序列检测(FSM状态机)
FSM有限状态机,是FPGA和数字IC相关岗位必须要掌握的知识点,在笔试和面试中都非常常见. (1)了解状态机:什么是摩尔型状态机,什么是米利型状态机,两者的区别是什么?一段式.二段式.三段式状态机的 ...
- 小梅哥FPGA学习笔记——状态机设计学习
状态机学习 状态机编写方式 设计目的 设计思路 设计代码编写 测试代码编写 仿真波形结果 状态机编写方式 状态机设计编写有三种方式,分别是一段式.两段式.三段式三种方式. 设计目的 通过一段式状态机编 ...
- FSM——squirrel状态机使用
FSM--squirrel状态机使用 1 FSM介绍 1.1 概念 FSM(finite state machine):有限状态机 是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型. 核 ...
- FSM mealy型状态机实现
FSM mealy型状态机实现 FSM 状态机的概念 FSM 状态 FSM 状态机 FSM 输入信号处理&状态切换 FSM 状态的行为 FSM(finite-state machine) 有限 ...
最新文章
- 18年总结及19年展望
- 编译安装 openswan-2.6.34
- 欢乐纪中B组周六赛【2019.3.9】
- JavaScript语言精粹笔记
- float 精度_为什么float后面要加f
- 【Win10 C盘压缩卷问题解答】:无法将卷压缩到超出任何不可移动的文件所在点
- CollapsingToolbarLayout用法详解(简洁易懂)
- vs2022 E1696 无法打开 源 文件 “string.h“
- 初识HTML(四)进阶:CSS基础、常用属性
- Spring Boot + Spring Security + JWT + 微信小程序登录
- day 09文件处理
- 牛顿迭代法计算平方根
- JAVA进阶知识点总结 4-Map HashMap LinkedHashMap Map的遍历方式 斗地主案例
- 硬盘分区修复和碎片整理命令
- 手机支付平台付款码分析
- Android apk上架国内应用市场流程
- 字节跳动笔试题(一)——18岁生日问题
- 教师资格证科目一综合素质
- Mysql 事件调度器详解(Event Scheduler)
- macos10.15.xx使用winclone8安装win系统