当前位置: 首页 > 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…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...