[转]Untiy学习 -一个简单的有限状态机(FSM)

2023-11-12

前言

参考资料:unity3D FSM有限状态机(状态设计模式)

核心

先列举有限数量的状态,让需要被控制的物体在状态中根据设定流转,并且每次只存在一个状态被激活。

三个方案

  • 声明一个enum字典,写入所有的状态

public enum EnemyStateEnum
{
    IDLE,//待机 -> 追击/死亡
    TRACE,//追击 -> 攻击/丢失/死亡
    LOST,//丢失 -> 待机/追击/死亡
    ATK1,//近战 -> 追击/丢失/死亡
    DIE,//死亡
}

后面是我想要让他能够流转的关系(提前写一下)

方案一 switch

public EnemyStateEnum traceState = EnemyStateEnum.IDLE;//声明一个状态属性

    void Update()
    {
        switch (traceState)
        {
            case EnemyStateEnum.IDLE:
                要做啥的事情();
                break;
            case EnemyStateEnum.TRACE:
                要做啥的事情();
                break;
            case EnemyStateEnum.LOST:
                要做啥的事情();
                break;
            case EnemyStateEnum.ATK1:
                要做啥的事情();
                break;
            case EnemyStateEnum.DIE:
                要做啥的事情();
                break;
        }
	}

然后在应触发转换的位置进行触发就行了。

这是非常偷懒的办法,并且局限性很大,如果状态非常多,或者想要区分状态开始、中间、结束,会非常麻烦

我写了很久才发现上面的有问题……紧急学了以下内容

方案二 参考资料:unity3D FSM有限状态机(状态设计模式)

1. 状态基类
状态基类需要3个虚方法,以及虚拟机对象

2. 拥有者泛型类
继承状态基类,构造出使用者对象

3. 玩家脚本类
在Start方法里构造new各个状态机类(传入枚举id,使用者this(自己)),new状态机对象,添加各个状态类对象。
在Update通过按键,并一直调用状态机的切换方法。
在LateUpdate()调用状态机的保持状态方法

4. 状态机类
包含添加状态类,切换状态类方法(控制Enter()),保存状态类方法(控制(Stay()))
加若干个状态类
每个状态具体有3种状态方法(OnEnter,OnStay,OnExit)需要重写来具体实现,通过OnExit()方法改变使用者的枚举id来切换状态
在这里插入图片描述

我做了一些调整,让onEnter每次只需单次调用

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// 状态机器类:由Player控制。完成状态的存储,切换,和状态的保持
/// </summary>
public class StateMachine
{

    //用来存储当前机器所控制的所有状态
    public Dictionary<int, StateBase> m_StateCache;

    //定义当前状态
    public StateBase m_currentState;

    //机器初始化时,没有上一个状态
    public StateMachine(StateBase beginState)
    {

        m_currentState = beginState;

        m_StateCache = new Dictionary<int, StateBase>();
        //把状态添加到集合中
        AddState(beginState);
        m_currentState.OnEnter();
    }

    public void AddState(StateBase state)
    {
        if (!m_StateCache.ContainsKey(state.ID))
        {
            m_StateCache.Add(state.ID, state);
            state.machine = this;
        }
    }

    //通过Id来切换状态
    public void TranslateState(int id)
    {
        if (!m_StateCache.ContainsKey(id))
        {
            Debug.Log("未添加ID");
            return;
        }

        if (m_currentState.ID == id)
        {
            Debug.Log("正处于"+ m_StateCache[id] + "状态");
            return;
        }

        m_currentState.OnExit();
        m_currentState = m_StateCache[id];
        m_currentState.OnEnter();
        Debug.Log("切换至" + m_StateCache[id] + "状态");
    }

    //状态保持
    public void Update()
    {
        if (m_currentState != null)
        {
            m_currentState.OnStay();
        }
    }
}

其他注意的点

在这里插入图片描述

  • 如果你改写了玩家脚本,记得要在LateUpdate()中进行调用,不然会拿不到stay()状态。
  • 可以将所有行为写在一个脚本文件的不同类里
    在这里插入图片描述
  • 并且通过owner关键字可以调用到你关联的脚本
    在这里插入图片描述

方案三

利用unity的动画状态机
在这里插入图片描述
创建空的动画用来表示事件,并通过bool开关进行控制

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[转]Untiy学习 -一个简单的有限状态机(FSM) 的相关文章

  • getResourceAsStream() 可以找到 jar 文件之外的文件吗?

    我正在开发一个应用程序 该应用程序使用一个加载配置文件的库 InputStream in getClass getResourceAsStream resource 然后我的应用程序打包在一个 jar文件 如果resource是在里面 ja
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 如何在控制器、服务和存储库模式中使用 DTO

    我正在遵循控制器 服务和存储库模式 我只是想知道 DTO 在哪里出现 控制器应该只接收 DTO 吗 我的理解是您不希望外界了解底层域模型 从领域模型到 DTO 的转换应该发生在控制器层还是服务层 在今天使用 Spring MVC 和交互式
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 玩!框架:运行“h2-browser”可以运行,但网页不可用

    当我运行命令时activator h2 browser它会使用以下 url 打开浏览器 192 168 1 17 8082 但我得到 使用 Chrome 此网页无法使用 奇怪的是它以前确实有效 从那时起我唯一改变的是JAVA OPTS以启用
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 获取 JVM 上所有引导类的列表?

    有一种方法叫做findBootstrapClass对于一个类加载器 如果它是引导的 则返回一个类 有没有办法找到类已经加载了 您可以尝试首先通过例如获取引导类加载器呼叫 ClassLoader bootstrapLoader ClassLo
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • Firebase 添加新节点

    如何将这些节点放入用户节点中 并创建另一个节点来存储帖子 我的数据库参考 databaseReference child user getUid setValue userInformations 您需要使用以下代码 databaseRef
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • 如何修复 JNLP 应用程序中的“缺少代码库、权限和应用程序名称清单属性”?

    随着最近的 Java 更新 许多人都遇到了缺少 Java Web Start 应用程序的问题Codebase Permissions and Application name体现属性 尽管有资源可以帮助您完成此任务 但我找不到任何资源综合的
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐

  • 在Web上运行Linux

    原文地址 http coolshell cn articles 4722 html more 4722 一个叫Fabrice Bellard的程序员写了一段Javascript在Web浏览器中启动Linux 原网页 我把这个网页iframe
  • Laya页面嵌套和Scene.destory导致的Bug

    Laya2 1 1 1 参考 预设使用 Laya给出了相同模块 逻辑代码也相同情况下 使用页面嵌 runtime的使用方案 但是该方案和Laya Scene open Laya Scene destroy等有冲突 会导致bug 当参考使用L
  • QT如何获取QListWidget的Scroll值

    你可以使用 QListWidget 的 verticalScrollBar 方法来获取一个指向该 QListWidget 的垂直滚动条的指针 然后 你可以使用这个滚动条的 value 方法来获取滚动条的当前值 例如 QListWidget
  • LeetCode刷题记录

    目录 1 数组中重复的数字 本题考验沟通 1 原地置换法 2 哈希表 Set 2 二维数组中的查找 1 暴力法 双for 2 线性查找 3 替换空格 1 字符数组 2 Java自带方法 4 从尾到头打印链表 1 递归法 附加练习 链表 5
  • cytoscape使用方法_APT干货

    中科新生命 成立于2004年 专注于质谱技术方法在科技服务 生物医药 精准医疗领域的应用开发 12年质谱服务经验 每年处理本数超万例 通过与中科院的技术合作及企业研发团队的自主创新 致力成为您优秀的生物技术合作伙伴 每日关键点 Cytosc
  • .NET Core:搭建私有Nuget服务器以及打包发布Nuget包

    使用docker搭建私有Nuget服务器 docker run d p 8080 80 v PWD nuget db var www db v PWD nuget packages var www packagefiles e NUGET
  • 【转】八大排序算法总结

    插入排序 1 直接插入排序 原理 将数组分为无序区和有序区两个区 然后不断将无序区的第一个元素按大小顺序插入到有序区中去 最终将所有无序区元素都移动到有序区完成排序 要点 设立哨兵 作为临时存储和判断数组边界之用 实现 Void Inser
  • BUAAOS-Lab0实验报告

    LAB0 初始操作系统 一 Note Exercise Thinking Exercise 0 1 echo bash ls Thinking 0 1 Shell简析 Exercise 0 2 gt gt gt Thinking 0 2 文
  • 微信公众平台开放 9 大高级接口,它有什么意义?

    微信的野心大大的 看看它的9大新接口吧 转自 http www ifanr com 366010 微信刚刚更新公众平台 向服务号开放微信认证 开放 9 大高级接口 增加开发者问答系统 并对微信公众平台的后台管理界面进行改版 其中最受关注的是
  • vmware安装redhat 9

    vmware安装redhat 9 1 镜像文件下载 1 1 镜像文件 2 安装系统 2 1 安装时语言 2 2 安装选项设置 2 2 1 手动磁盘分区 2 2 2 设置root密码 允许通过ssh使用密码方式登录root 2 3 开始安装系
  • 最实用的应急响应笔记思路小结

    0x00 事件应急响应的流程分析 事件整个类型大致归类于 事件表现 信息收集 确认攻击类型 事件追查 修复 1 事件的表现 网站类型 被篡改 信息丢失 乱码等 文件类型 被篡改 丢失 泄露等 系统类型 系统卡顿 CPU爆满 服务宕机等 流量
  • 普通大学生如何拿到大厂offer?敖丙教你一招致胜!

    提到敖丙 大家应该并不陌生 三太子敖丙 CSDN博客大V 时年24岁 曾供职于阿里巴巴 蘑菇街等大厂 专注于Java后端研发领域 公众号 三太子敖丙 主理人 敖丙虽然才24岁 但已有五年的职场经验 并且这五年的职场打拼已帮助其实现了财富自由
  • 最新人机对话工具:GPT4介绍(ChatGPT升级版 支持图片且更智能)

    这里写自定义目录标题 显著提升特点 介绍 能力对比 考试能力 知识水平 语言能力 视觉能力 使用方法指南 今天偶然发现期待已久的GPT 4发布了 比上一版的ChatGPT GPT 3 5 性能还好 最主要是支持图片输入 就增加了很多新的场景
  • LeetCode 每日一题 2022_list

    网页链接 LeetCode 坚持住 小镁铝 2022年1月每日一题记录
  • Zabbix--部署--03--proxy安装--6.0

    Zabbix 部署 03 proxy安装 6 0 1 介绍 1 1 官方安装文档 https www zabbix com cn download 1 2 环境介绍 操作系统 centos7 zabbix版本 6 0 LTS 2 准备工作
  • 循环中调用异步接口获取数据

    前言 遇到这样一个需求 调用接口 返回一个新闻列表 再循环这个新闻列表 用每个新闻的id异步请求这个新闻的视频地址 这就需要在循环里调用接口 如果用for循环 接口还没请求完成 for循环就已经执行完了 所以改成promise去处理 开始
  • 支持可变函数调用的php函数,可变函数 - PHP 7 中文文档

    可变函数 PHP 支持可变函数的概念 这意味着如果一个变量名后有圆括号 PHP 将寻找与变量的值同名的函数 并且尝试执行它 可变函数可以用来实现包括回调函数 函数表在内的一些用途 可变函数不能用于例如 echo php7 function
  • 在数学空间中,物理分辨率可能失去了意义(behind the paper)

    写在前面 2020 01到2021 07于我来说 是非常艰难的两年 所以这段时间一直也没有在CSDN持续整理 转载一些CV知识了 而这期间经历了4 5轮审稿 从nature辗转nature biotechnology 终于把第一篇工作发表了
  • linux服务器安装配置jdk

    1 下载jdk 用wget命令 下载linux对应版本的jdk到 usr local 然后解压 cd usr local wget http download oracle com otn pub java jdk 7u79 b15 jdk
  • [转]Untiy学习 -一个简单的有限状态机(FSM)

    前言 参考资料 unity3D FSM有限状态机 状态设计模式 核心 先列举有限数量的状态 让需要被控制的物体在状态中根据设定流转 并且每次只存在一个状态被激活 三个方案 声明一个enum字典 写入所有的状态 public enum Ene