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 有限状态机简介 有限状态机(英语:finite-state machine,缩写:FSM),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型 在游戏开发中应用有限状态机ÿ…...
数据库参数 PGA_AGGREGATE_LIMIT 限制进程大小
在自动化 PGA 内存管理模式下,Oracle 数据库通过动态控制分配到工作区的 PGA 内存量来尝试遵从 PGA_AGGREGATE_TARGET 值。但是,有时因为以下原因,PGA 内存使用量可能会超过 PGA_AGGREGATE_TARGET 设置: PGA_AGGREGATE_TARGET 设置…...
208.【2023年华为OD机试真题(C卷)】停车场车辆统计(贪心算法实现-JavaPythonC++JS实现)
🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-停车场车辆统计二.解题思路三.题解代码Python题…...
JS 作用域和预解析
作用域 通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。 作用域分为全局作用域和局…...
各种锁的概述
乐观锁与悲观锁 悲观锁指对数据被外界修改持保守态度,认为数据很容易就会被其他线程修改,所以在数据被处理前先对数据进行加锁,并在整个数据处理过程中,使数据处于锁定状态。 悲观锁的实现往往依靠数据库提供的锁机制࿰…...
【docker笔记】Docker容器数据卷
Docker容器数据卷 卷就是目录或者文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性 卷的设计目的就是数据的持久化,完全独…...
大前端nestjs入门教程系列(四):如何nestjs整合mysql数据库
经过前面的几篇文章,想必大家已经对nestjs有了基础的了解,那么这篇文章就带大家玩玩数据库,学会了这篇,就离大前端又进了一步 Nest与数据库无关,使你可以轻松地与任何 SQL 或 NoSQL 数据库集成。 根据你的喜好…...
Android studio环境配置
1.搜索android studio下载 Android Studio - Download 2.安装 3.配置环境 配置gradle,gradle参考网络配置。最后根据项目需求选择不同的jdk。...
017、使用包、单元包及模块来管理日渐复杂的项目
在编写较为复杂的项目时,合理地对代码进行组织与管理很重要,因为我们不太可能记住代码中所有的细枝末节。只有按照不同的特性来组织或分割相关功能的代码,我们才能够清晰地找到实现指定功能的代码片段,或确定哪些地方需要修改。 到…...
Git提交规范详解
在团队协作开发中,Git作为版本控制系统,其提交信息的清晰性和一致性至关重要。通过定义特定的提交类型和格式,我们可以更好地追踪项目历史,提高代码审查效率,并方便生成高质量的变更日志。以下是几种常见的Git提交类型…...
线程与UI操作
子线程中不能执行UI操作。 UI 操作指的是与用户界面(User Interface)相关的操作,包括但不限于以下几种: 更新视图:例如更改 TextView 的文本内容、设置 ImageView 的图片等。处理用户输入:例如响应按钮点…...
ELK企业级日志系统分析系统
目录 一、什么是ELK? 二、ELK三大组件 三、ELK的工作原理 四、完整日志系统基本特征 一、什么是ELK? ELK平台是一套完整的日志集中处理解决方案,将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用, 完成更强大的用…...
11.23 校招 实习 内推 面经
绿*泡*泡: neituijunsir 交流裙 ,内推/实习/校招汇总表格 1、校招&社招&实习丨图森未来传感器标定工程师招聘(内推) 校招&社招&实习丨图森未来传感器标定工程师招聘(内推) 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个月,技术退步一大半了。。。
先说一下自己的情况,本科生,20年通过校招进入深圳某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...
设计模式的艺术P1基础—2.2 类与类的UML图示
设计模式的艺术P1基础—2.2 类与类的UML图示 在UML 2.0的13种图形中,类图是使用频率最高的两种UML图之一(另一种是用于需求建模的用例图),它用于描述系统中所包含的类以及它们之间的相互关系,帮助人们简化对系统的理解…...
PCB 的正片、负片那些事儿
最近在 PCB 打样的过程中遇到了 PCB 的正片层和负片层的问题,故以此记录一下。 问题产生的原因是在投产 PCB 时发现生产稿的 Gerber 图形和 PCB 设计有区别,如图所示,左边为某 PCB 内层,右边为对应层生产稿的 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)的基础知识
上一篇: C#,入门教程(12)——数组及数组使用的基础知识https://blog.csdn.net/beijinghorn/article/details/123918227 字符串的使用与操作是必需掌握得滚瓜烂熟的编程技能之一!!!!! C#语言实…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
