当前位置: 首页 > news >正文

FSM(有限状态机)

FSM有限状态机

  • FSM
    • 创建控制有限状态机的脚本
    • 设置FSM状态机下的各个状态
    • 添加测试类
    • FSM的优点

FSM

虽然Unity已经有了动画状态机,但是为了代码的开放封闭原则,这时FSM有限状态机的作用就凸显了出来。

创建控制有限状态机的脚本

先创建一个脚本用来控制有限状态机(FSM),主要用于切换状态。
首先用一个枚举列举出各个状态

public enum StateType
{ldle,run,jumping,dying,shooting
}

然后我们需要一个容器来保存当前的状态,用字典存储起来方便随后的更改下一状态随后初始化类,将字典创建,并添加两个增加和设置状态的方法,最后再每一帧执行。代码如下

  //当前在运行什么状态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状态机下的各个状态

接下来将展示其中的一个状态,以此类推可以写出其他的状态

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秒后改变状态为跑

添加测试类

但我们将前两个脚本写完,就可以添加测试类,也就是增加各个状态以及设置初始状态的操作后就可以正常运行了

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就可以直接创建新的脚本就能实现增加其他状态了

相关文章:

FSM(有限状态机)

FSM有限状态机FSM创建控制有限状态机的脚本设置FSM状态机下的各个状态添加测试类FSM的优点FSM 虽然Unity已经有了动画状态机&#xff0c;但是为了代码的开放封闭原则&#xff0c;这时FSM有限状态机的作用就凸显了出来。 创建控制有限状态机的脚本 先创建一个脚本用来控制有限…...

奇妙的background-clip:text

我们在学习CSS3时&#xff0c;一个背景属性background-clip用来对背景进行裁剪&#xff0c;即指定背景绘制的区域&#xff0c;通常我们使用的几个属性如下&#xff1a;值说明border-box默认值。背景绘制在边框方框内&#xff08;剪切成边框方框&#xff09;。padding-box背景绘…...

Vmware虚拟机无法联通主机解决方法二

昨天在遇到了VMware 虚拟机无法联通主机&#xff0c;导致我在CentOS-7 搭建的伪Hadoop3 服务&#xff0c;无法访问管理平台&#xff0c;使用将网络编辑器修改为“桥接”模式解决。今天在学习HBase 时&#xff0c;昨天的问题又重新了&#xff0c;我通过SSH 工具MobaXterm 都无法…...

Boost资料整理备忘

Boost资料整理备忘 网络资源 书籍: The Boost C Libraries官方文档 Boost Library Documentation random boost.randomBoost随机库的简单使用&#xff1a;Boost.Random(STL通用)tutorialstd::random boost::asio Boost.Asio 网络编程 - 基本原理Boost.Asio DocBoost定时器 网…...

规则引擎与风控系统01:新问题,新挑战

如果说在支付系统中使用设计模式,以及开发自定义协议的物联网这两类应用还不够酷的话,那么接下来,咱们就来学一点高逼格的技术吧。 在互联网已经日益普遍的时代,不管是开发2C应用还是2B应用,相信大部分的开发者都有过处理复杂业务逻辑的经历,比如电商、社交、电子政务、O…...

Oracle-00-卸载篇

这里给出企业级的Oracle 10g的卸教程,新安装的19c并没有正经去做卸载的操作,为了后面教程的进度,这里就先借用下10g,如果有需要会重新更新19c的卸载教程 windows服务中将Oracle所有服务全部停掉 选中Oracle - OraDb10g_home2->Oracle Installation Products->Univers…...

Java线程池使用与原理解析1(线程池优点、使用方法、参数含义及线程池运转机制)

为什么要使用线程池&#xff1f; JDK1.5后JUC包添加了线程池相关接口&#xff0c;在Java诞生之初并没有线程池这个概念。刚开始Java程序都是自行创建线程去处理任务。随着应用使用的线程越来越多&#xff0c;JDK开发者们发现有必要使用一个统一的类来管理这些线程&#xff0c;…...

windows下编译leveldb(动态库+静态库)

环境准备 1&#xff09;下载cmake并安装 下载路径: https://cmake.org/download/2&#xff09;下载leveldb源码 git clone https://github.com/google/leveldb.git3&#xff09;下载googletest和benchmark&#xff0c;cmake编译时需要 # 进入leveldb源码路径下的third_part…...

如何用76行代码写一个AI微信机器人......

本期博客主要介绍如何使用 微信SDK 和 AI聊天接口 &#xff0c;实现 微信机器人功能。 准备 电脑需要安装Go环境&#xff0c;这个可以直接参考菜鸟教程&#xff1a;Go 语言环境安装&#xff0c;知道CSDN的同学基本能在半小时内装好吧…&#xff08;可选&#xff09;一个编译器…...

拿下域控后,我还是对大佬的操作念念不忘

历来攻防演练中&#xff0c;我都笃信一个道理——吃饱了才有力气干活。所以&#xff0c;在清晨的客户现场&#xff0c;当看到大佬满意地吃完了我带来的煎饺&#xff0c;我知道这一战&#xff0c;我们作为攻击队&#xff0c;基本已经拿下了。 虽然说的每一句话都带着一股醋味儿…...

实习-----Mybatis 框架

Mybatis 框架ORM持久化介绍 了解什么是“持久化”即把数据&#xff08;如内存中的对象&#xff09;保存的磁盘的某一文件中ORM概念ORM&#xff0c;即Object Relational Mapping&#xff0c;它是对象关系映射的简称。它的作用是在关系型数据库和对象之间作一个映射&#xff0c;是…...

【Linux】孤儿进程 | 环境变量 | 命令行参数 | 进程优先级

文章目录1. 孤儿进程2. 环境变量1. PATH环境变量证明ls是系统指令修改自己写的可执行程序对应路径2. env——查看系统环境变量3. 获取环境变量envpenvirongetenv 函数获取 (主流)4. 总结3 . 命令行参数理解命令行参数4. 进程优先级优先级与权限的区分为什么会有优先级&#xff…...

Matlab字符串相关操作-拼接、格式化

常见的有三种方法&#xff1a;向量拼接、strcat函数和sprintf函数1、向量拼接在matlab中字符串本质上也是一个向量&#xff0c;可以通过矩阵运算来实现字符串的拼接&#xff0c;这里随便输入两个字符串a1和b1&#xff0c;用矩阵形式进行拼接&#xff1a;a1 I love;b1 Matlab…...

死磕Spring系列,SpringBoot启动流程

参考文章&#xff1a;SpringBoot启动流程系列讲解 参考视频&#xff1a;SpringBoot启动流程 吐血推荐视频&#xff1a;史上最完整的Spring启动流程 超级好文&#xff1a;SpringBoot执行原理 参考文章&#xff1a;SpringBoot资源接口ResourceLoader和Resource学习 参考文章&…...

关于条件变量wait操作中锁的作用

condition_variable::wait的锁 在看C Concurrency in Action 6.2.3节的线程安全队列时&#xff0c;其对condition_variable的使用与常规用法有点不同&#xff0c;我对condition_variable::wait中锁的作用产生了疑惑&#xff1a;它究竟是保护的谁&#xff1f;于是找到了 C noti…...

JUC并发编程与源码分析笔记09-原子类操作之十八罗汉增强

基本类型原子类 AtomicInteger、AtomicBoolean、AtomicLong。 常用API&#xff1a; public final int get();// 获取当前的值 public final int getAndSet(int newValue);// 获取当前值&#xff0c;并设置新值 public final int getAndIncrement();// 获取当前的值&#xff0…...

含分布式电源的配电网日前两阶段优化调度模型(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…...

FreeRTOS的Delay函数

两个Delay函数有两个延时函数vTaskDelay&#xff1a;至少等待指定个数的Tick Interrupt才能变为就绪态xTaskDelayUtil&#xff1a;等待到指定的绝对时刻&#xff0c;才能变为就绪态个人感觉这两个延时函数就是&#xff0c;比如一个我等3个小时&#xff0c;一个是我等到下午3点的…...

HCIA-HarmonyOS Application Developer——题目集1

题目1 1、一位开发人员在设计应用程序时&#xff0c;添加了一个Text组件和Button组件&#xff0c;开发样图如下所示。该开发者不能选择哪种布局方式来放置组件? A、StackLayout B、DependentLayout C、DirectionalLayout D、TableLayout 解析&#xff1a;&#xff08;A&#…...

高性能 Message ToJavaBean 工具 【easy.server.mapper】

easy.server.mapper 介绍 后端开发中&#xff0c;消息转换常见问题 Map 中的数据 转换成实体Bean数组 中的数据 转换成实体BeanServet 中的 param 转换成实体Bean 以上的三个问题是最常见的消息转换困扰。 以Map 举例 常见做法是 手动转换 Map<String,Object> da…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...