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

Unity | 渡鸦避难所-6 | 有限状态机控制角色行为逻辑

1 有限状态机简介

有限状态机(英语:finite-state machine,缩写:FSM),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型

在游戏开发中应用有限状态机,能够将复杂的行为逻辑分解为一组简单的状态和转换规则,每个状态都可以独立地处理其逻辑,使代码更加结构化和组织化。同时可以方便的添加新的状态和转换规则,以适应游戏的需求。而且避免了在每帧中检查所有可能的行为,只需要处理当前状态的逻辑

Unity 中的 Animator Controller 使用状态机来管理各种动画状态和它们之间的过渡。但角色处于不同的状态时,除了播放对应的动画外,也会执行相关的逻辑,使用状态机来控制角色的行为也会为开发带来很大的便利

2 动画状态机

1 动画工作流程

Unity 的动画系统基于动画剪辑的概念;动画剪辑包含某些对象应如何随时间改变其位置、旋转或其他属性的相关信息。每个剪辑可视为单个线性录制。来自外部的动画剪辑由美术师或动画师使用第三方工具(例如 Autodesk® 3ds Max® 或 Autodesk® Maya®)创建而成,或者来自动作捕捉工作室或其他来源

然后,动画剪辑将编入称为 Animator Controller 的一个类似于流程图的结构化系统中。Animator Controller 充当状态机,负责跟踪当前应该播放哪个剪辑以及动画应该何时改变或混合在一起

2 动画状态机

角色或其他动画游戏对象通常具有若干不同的动画,这些动画对应于该角色或对象可在游戏中执行的不同动作。例如,角色可以在空闲时轻微呼吸或摇摆,在得到指令时行走,以及从平台上跌落时恐慌地抬起手臂。Mecanim 使用类似于流程图的可视化布局系统来表示状态机,从而控制需要在角色或对象上使用的动画剪辑并对这些动画剪辑排序

状态机的基本思想是使角色在某一给定时刻进行一个特定的动作。动作类型可因游戏类型的不同而不同,常用的动作包括空闲、行走、跑步、跳跃等,其中每一个动作被称为一种状态。在某种意义上,角色处于行走、空闲或者其它的状态中。一般来说,角色从一个状态立即切换到另一个状态是需要一定的限制条件的。比如角色只能从跑步状态切换到跑跳状态,而不能直接由静止状态切换到跑跳状态。角色从当前状态进入下一个状态的选项被称为状态过渡条件。状态集合、状态过渡条件以及记录当前状态的变量放在一起,形成了一个状态机

状态及其过渡条件可以通过图形来表达,其中的节点表示状态,而弧线(节点间的箭头)表示状态过渡。可以将当前状态视为放置在节点之一上的标记或亮点,然后只能沿箭头之一跳转到另一个节点

状态机对于动画的重要意义在于用户可以通过很少的代码对状态机进行设计和升级。每一个状态有一个与之关联的运动,只要状态机处于此状态,就会播放此运动。从而让动画师或设计师方便地定义动作顺序,而不必去关心底层代码的实现

Unity 的动画状态机提供了一种纵览角色所有动画剪辑的方法,并且允许通过游戏中的各种事件(如用户输入)来触发不同的动画效果

动画状态机可以通过 Animator Controller 窗口来创建,这些状态机如下所示:

动画状态机包括动画状态、动画过渡和动画事件,而复杂的状态机还可以含有简单的子状态机,更多信息请参阅文档「https://docs.unity3d.com/cn/2021.2/Manual/AnimationOverview.html」

3 Animator Controller

1 创建资源

Animator Controller 资源是在 Unity 内创建的,可以为角色或对象维护一组动画,更多信息请参阅:「https://docs.unity3d.com/cn/2021.2/Manual/Animator.html」

可通过以下方式创建 Animator Controller:

  • 从 Project 视图中,选择 Create > Animator Controller

  • 在 Project 视图中右键单击并选择 Create > Animator Controller

  • 从 Assets 菜单中,选择 Assets > Create > Animator Controller

2 查看视图

在 Animator 窗口中可创建、查看和修改 Animator Controller 资源,视图内使用鼠标中键或按住 Alt/Option 键拖拽可平移视图,更多信息请参阅文档:「https://docs.unity3d.com/cn/2021.2/Manual/AnimatorWindow.html」

可通过以下方式查看 Animator Controller 视图:

  • 从 Assets 菜单中,选择 Window > Animation > Animator

  • 双击 Animator Controller 资源

3 整理状态

双击角色的 Animator Controller,可以看到对应的状态机,当前状态机会把所有的动作依次执行一遍

游戏中暂时需要的状态包括: idle、move、attack、define、skill、die,可以整理已经存在的状态,也可以新建状态

  • 整理状态:断开转换,选中状态或者箭头,点击-号

  • 新建状态:拖动动画资源到窗口,自动创建状态

整理后的状态机:

3 行为状态机

在 Animator Controller 中可以看到,每个状态机包含多个状态节点,每个状态节点包含一个状态及多个转换:

选中转换,查看转换信息,每个转换包含多个过渡条件,同时转换需要有来源及目标,即从什么状态转换到什么状态

了解 Unity 的动画状态机后,根据这些基本要素,构建行为状态机

1 过渡条件

从当前状态进入下一个状态的选项被称为状态过渡条件,因此,条件类中需要一个有返回值的函数的委托,来判定是否进入目标状态

public class Condition
{private Func<bool> _func { get; }public Condition(Func<bool> func){_func = func;}public bool Evaluate() => _func.Invoke();
}
2 转换

转换中包含目标状态及过渡条件

public class Transition<TEnum> where TEnum : Enum
{public TEnum To { get; }public Condition Condition { get; }public Transition(TEnum to, Condition condition){To = to;Condition = condition;}
}
3 状态

状态中包含进入、更新、退出等事件,为了与角色调用方便,额外增加状态所属者

public class State<TOwner> where TOwner : class
{public readonly TOwner Owner;public State(TOwner owner){Owner = owner;}public virtual void OnEnter(){}public virtual void OnUpdate(){}public virtual void OnFixedUpdate(){}public virtual void OnExit(){}
}
4 状态节点

状态及其对应的转换构成一个状态节点

public class StateNode<TEnum, TOwner> where TEnum : Enum where TOwner : class
{public TEnum Key { get; }public State<TOwner> State { get; }public HashSet<Transition<TEnum>> Transitions { get; }public StateNode(TEnum key, State<TOwner> state){Key = key;State = state;Transitions = new HashSet<Transition<TEnum>>();}public void AddTransition(TEnum to, Condition condition){Transitions.Add(new Transition<TEnum>(to, condition));}
}
5 状态机

状态集合、状态过渡条件以及记录当前状态的变量放在一起,形成了一个状态机

相关文章:

Unity | 渡鸦避难所-6 | 有限状态机控制角色行为逻辑

1 有限状态机简介 有限状态机&#xff08;英语&#xff1a;finite-state machine&#xff0c;缩写&#xff1a;FSM&#xff09;&#xff0c;简称状态机&#xff0c;是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型 在游戏开发中应用有限状态机&#xff…...

数据库参数 PGA_AGGREGATE_LIMIT 限制进程大小

在自动化 PGA 内存管理模式下&#xff0c;Oracle 数据库通过动态控制分配到工作区的 PGA 内存量来尝试遵从 PGA_AGGREGATE_TARGET 值。但是&#xff0c;有时因为以下原因&#xff0c;PGA 内存使用量可能会超过 PGA_AGGREGATE_TARGET 设置&#xff1a; PGA_AGGREGATE_TARGET 设置…...

208.【2023年华为OD机试真题(C卷)】停车场车辆统计(贪心算法实现-JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-停车场车辆统计二.解题思路三.题解代码Python题…...

JS 作用域和预解析

作用域 通常来说&#xff0c;一段程序代码中所用到的名字并不总是有效和可用的&#xff0c;而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性&#xff0c;增强了程序的可靠性&#xff0c;减少了名字冲突。 作用域分为全局作用域和局…...

各种锁的概述

乐观锁与悲观锁 悲观锁指对数据被外界修改持保守态度&#xff0c;认为数据很容易就会被其他线程修改&#xff0c;所以在数据被处理前先对数据进行加锁&#xff0c;并在整个数据处理过程中&#xff0c;使数据处于锁定状态。 悲观锁的实现往往依靠数据库提供的锁机制&#xff0…...

【docker笔记】Docker容器数据卷

Docker容器数据卷 卷就是目录或者文件&#xff0c;存在于一个或多个容器中&#xff0c;由docker挂载到容器&#xff0c;但不属于联合文件系统&#xff0c;因此能够绕过Union File System提供一些用于持续存储或共享数据的特性 卷的设计目的就是数据的持久化&#xff0c;完全独…...

大前端nestjs入门教程系列(四):如何nestjs整合mysql数据库

经过前面的几篇文章&#xff0c;想必大家已经对nestjs有了基础的了解&#xff0c;那么这篇文章就带大家玩玩数据库&#xff0c;学会了这篇&#xff0c;就离大前端又进了一步 Nest与数据库无关&#xff0c;使你可以轻松地与任何 SQL 或 NoSQL 数据库集成。 根据你的喜好&#xf…...

Android studio环境配置

1.搜索android studio下载 Android Studio - Download 2.安装 3.配置环境 配置gradle&#xff0c;gradle参考网络配置。最后根据项目需求选择不同的jdk。...

017、使用包、单元包及模块来管理日渐复杂的项目

在编写较为复杂的项目时&#xff0c;合理地对代码进行组织与管理很重要&#xff0c;因为我们不太可能记住代码中所有的细枝末节。只有按照不同的特性来组织或分割相关功能的代码&#xff0c;我们才能够清晰地找到实现指定功能的代码片段&#xff0c;或确定哪些地方需要修改。 到…...

Git提交规范详解

在团队协作开发中&#xff0c;Git作为版本控制系统&#xff0c;其提交信息的清晰性和一致性至关重要。通过定义特定的提交类型和格式&#xff0c;我们可以更好地追踪项目历史&#xff0c;提高代码审查效率&#xff0c;并方便生成高质量的变更日志。以下是几种常见的Git提交类型…...

线程与UI操作

子线程中不能执行UI操作。 UI 操作指的是与用户界面&#xff08;User Interface&#xff09;相关的操作&#xff0c;包括但不限于以下几种&#xff1a; 更新视图&#xff1a;例如更改 TextView 的文本内容、设置 ImageView 的图片等。处理用户输入&#xff1a;例如响应按钮点…...

ELK企业级日志系统分析系统

目录 一、什么是ELK&#xff1f; 二、ELK三大组件 三、ELK的工作原理 四、完整日志系统基本特征 一、什么是ELK&#xff1f; ELK平台是一套完整的日志集中处理解决方案&#xff0c;将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用&#xff0c; 完成更强大的用…...

11.23 校招 实习 内推 面经

绿*泡*泡&#xff1a; neituijunsir 交流裙 &#xff0c;内推/实习/校招汇总表格 1、校招&社招&实习丨图森未来传感器标定工程师招聘&#xff08;内推&#xff09; 校招&社招&实习丨图森未来传感器标定工程师招聘&#xff08;内推&#xff09; 2、校招 | 吉…...

Python战机

基础版 import pygame import random# 设置游戏屏幕大小 screen_width 480 screen_height 600# 定义颜色 WHITE (255, 255, 255) RED (255, 0, 0) GREEN (0, 255, 0) BLUE (0, 0, 255)# 初始化pygame pygame.init()# 创建游戏窗口 screen pygame.display.set_mode((scre…...

外包做了5个月,技术退步一大半了。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;20年通过校招进入深圳某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...

设计模式的艺术P1基础—2.2 类与类的UML图示

设计模式的艺术P1基础—2.2 类与类的UML图示 在UML 2.0的13种图形中&#xff0c;类图是使用频率最高的两种UML图之一&#xff08;另一种是用于需求建模的用例图&#xff09;&#xff0c;它用于描述系统中所包含的类以及它们之间的相互关系&#xff0c;帮助人们简化对系统的理解…...

PCB 的正片、负片那些事儿

最近在 PCB 打样的过程中遇到了 PCB 的正片层和负片层的问题&#xff0c;故以此记录一下。 问题产生的原因是在投产 PCB 时发现生产稿的 Gerber 图形和 PCB 设计有区别&#xff0c;如图所示&#xff0c;左边为某 PCB 内层&#xff0c;右边为对应层生产稿的 Gerber 图形&#x…...

QT应用篇:QT解析与生成XML文件的四种方式

四种常见的解析 XML 的方式(DOM、SAX、以及基于 Qt 的 XmlStreamReader)各有自己的优缺点,适合不同的应用场景。 DOM 适合小型且结构简单的 XML 文件,需要频繁修改和操作整个文档结构的情况。SAX 适合大型 XML 文件,以及只需读取不需要修改的情况。基于 Qt 的 XmlStreamRe…...

Android 正圆

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"wrap_content"android:layout_height"wrap_content"android:padding&…...

C#,入门教程(13)——字符(char)及字符串(string)的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(12)——数组及数组使用的基础知识https://blog.csdn.net/beijinghorn/article/details/123918227 字符串的使用与操作是必需掌握得滚瓜烂熟的编程技能之一&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; C#语言实…...

Tracert 与 Ping 程序设计与实现(2024)

1.题目描述 了解 Tracert 程序的实现原理&#xff0c;并调试通过。然后参考 Tracert 程序和计算机网络教材 4.4.2 节&#xff0c; 计算机网络 课程设计指导书 2 编写一个 Ping 程序&#xff0c;并能测试本局域网的所有机器是否在线&#xff0c;运行界面如下图所示的 QuickPing …...

浅谈接口自动化测试

前言 自动化测试&#xff0c;算是近几年比较火热的一个话题&#xff0c;当然&#xff0c;更是软件测试未来的一个发展趋势。未来&#xff0c;功能测试等非核心的测试工作&#xff0c;都将被外包。 想要在软件测试这个行业继续前行&#xff0c;就必须拥有核心竞争力&#xff0…...

Hyperledger Fabric 核心概念与组件

要理解超级账本 Fabric 的设计&#xff0c;首先要掌握其最基本的核心概念与组件&#xff0c;如节点、交易、排序、共识、通道等。 弄清楚这些核心组件的功能&#xff0c;就可以准确把握 Fabric 的底层运行原理&#xff0c;深入理解其在架构上的设计初衷。知其然&#xff0c;进…...

【C语言题解】 | 101. 对称二叉树

101. 对称二叉树 101. 对称二叉树代码 101. 对称二叉树 这个题目要求判断该二叉树是否为对称二叉树&#xff0c;此题与上一题&#xff0c;即 100. 相同的树 这个题有异曲同工之妙&#xff0c;故此题可借鉴上题。 我们先传入需要判断二叉树的根节点&#xff0c;通过isSameTree()…...

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机掉线自动重连(C#)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机掉线自动重连&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机的掉线自动重连的技术背景通过PnP事件函数检查Baumer工业相机是否掉线在NEOAPI SDK里实现相机掉线重连方法&#xff1a;工业相机掉线重连测试演示图…...

[Vulnhub靶机] DriftingBlues: 5

[Vulnhub靶机] DriftingBlues: 5靶机渗透思路及方法&#xff08;个人分享&#xff09; 靶机下载地址&#xff1a; https://download.vulnhub.com/driftingblues/driftingblues5_vh.ova 靶机地址&#xff1a;192.168.67.24 攻击机地址&#xff1a;192.168.67.3 一、信息收集 …...

26 数字验证

效果演示 实现了一个简单的数字密码输入表单&#xff0c;用户需要输入一个4位数字密码来验证身份。表单包含一个标题、描述、输入字段、两个按钮和一个关闭按钮。输入字段是一个4位数字密码&#xff0c;用户需要在每个输入框中输入数字来输入密码。两个按钮分别是“验证”和“清…...

echarts - xAxis.type设置time时该如何使用formatter的分级模板

echarts 文档中描述了x轴的多种类型 一、type: ‘value’ ‘value’ 数值轴&#xff0c;适用于连续数据。 此时x轴数据是从零开始&#xff0c;有数据大小的区分。 【注意】 因为xAxis.data是为category服务的&#xff0c;所以xAxis.data里面设置的数据无效。 二、type: ‘ca…...

【代码随想录】刷题笔记Day47

前言 又过了个愉快的周末~大组会终于不用开了&#xff0c;理论上已经可以回家了&#xff01;但是我多留学校几天吧&#xff0c;回家实在太无聊了&#xff0c;也没太多学习的氛围 198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; dp[i]含义 考虑下标i&#xff08;包括…...

6.1 截图工具HyperSnap6简介

图片是组成多媒体作品的基本元素之一&#xff0c;利用图片可以增强多媒体作品的亲和力和说说服力。截取图片最简单的方法是直接按下键盘上的“PrintScreen”键截取整个屏幕或按下“AltPrintScreen”组合键截取当前活动窗口&#xff0c;然后在画笔或者其它的图片处理软件中进行剪…...

怎么给你新网站做seo/seo系统培训班

王者荣耀8月23日更新失败怎么处理?每次大版本更新都会出现各种问题&#xff0c;官方对此也是很无奈&#xff0c;不过问题总是要解决的&#xff0c;官方也整体了常见问题以及处理&#xff0c;如果你遇到麻烦了&#xff0c;可以按照步骤处理!王者荣呀哦更新失败处理方法&#xf…...

网站建设的基本步骤是哪些/海洋网络推广效果

欢迎点击上方 电信科学 关注我们高性能网络协议栈兼容性研究姜惠友, 李峻峰, 李丹清华大学&#xff0c;北京 100084【摘 要】人工智能系统的海量数据处理需要很高的网络吞吐来支撑&#xff0c;网络协议栈作为上层人工智能应用和底层高速硬件网卡之间的桥梁&#xff0c;对整个系…...

山东烟台建设厅网站/最近实时热点事件

mounted() {this.onResize();window.addEventListener(resize, this.onResize);},methods: {// 改变浏览器窗口的大小onResize() {console.log(处理窗口缩放时要处理的逻辑操作&#xff01;);}, ]beforeDestroy() {// 移除绑定的onResize事件监听window.removeEventListener(&q…...

建站之星凡客/5000元做百度推广效果怎么样

1、简述 Feign 是 Netflix 公司开发的一个声明式的 REST 调用客户端(调用远程的restful风格的http接口 的一个组件);是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。Feign通过处理注解,将请求…...

淮南做网站的公司/seo外链是什么意思

为什么80%的码农都做不了架构师&#xff1f;>>> 总结如下&#xff1a; 1、elementui的loading其实是fullscreen才是全局唯一&#xff0c;不然会Loading.service一次创建一次实例 2、elementui的loading需要异步关闭&#xff0c;要包在$nextTick()里面&#xff0c;原…...

自学网站有哪些/百度权重

2019独角兽企业重金招聘Python工程师标准>>> 默认Menu上的Icon必须通过iconField和iconFunction去指定&#xff0c;但是这两种方式都必须用嵌入资源Class名字去指定Icon&#xff0c;如果想用动态的图片&#xff08;比如URL&#xff09;作为Menu的Icon&#xff0c;就…...