尝试自主打造一个有限状态机(二)

news2024/11/14 10:35:54

前言

        上一篇文章我们从理论角度去探索了状态机的定义、组成、作用以及设计,对状态机有了一个基本的认识,这么做有利于我们更好地去分析基于实际应用的状态机,以及在自主设计状态机时也能更加地有条不紊。本篇文章将从状态机的实际应用出发,分析基于角色控制的状态机是如何进行设计的。

声明

        本系列文章要求读者具备一定的C#编程基础,同时对接口和抽象类、继承关系、设计模式以及面向对象等知识有所了解,在文章中我会对这些知识进行简要的阐述,对于描述有误的地方敬请指正。

基于角色控制的状态机

1.定义

        基于角色控制的状态机是用于管理一个角色的状态的,在动作类游戏中角色的状态往往比较多,并且状态之间的过渡关系也比较繁杂,那么我们就可以为此打造一个状态机来更好地开发和维护这个部分。

        从Unity3D的Animator去分析,首先一个角色通常是通过一个.controller文件来管理角色的状态的,这个. controller文件就像一个系统,从Animator的界面可以看到这个系统中包括了定义的状态、状态之间的连接以及状态过渡的条件参数等,而每个状态和状态之间的连接都有一些属性可以进行设置,由于状态机的应用不仅限于像Animator那样用于动画,所以这些属性应该根据状态机的实际应用场景去定义,如果用于动画,那么状态的属性可以是动画源文件和动画播放速度等。

2.组成

        通常一个角色只需要使用一个状态机去控制即可,这个状态机属于角色控制的一部分,它至少应该包括角色状态类、角色状态转换路径类和角色状态机类三个部分,除此之外我们还可以把角色状态的执行逻辑与角色状态分离将其单独作为一个类,但是它仍然属于状态机。同时角色控制是与输入相关联的,所以角色状态的转换将由当前状态与输入共同决定,输入不属于角色控制,所以也就不作为状态机的组成部分,除此之外还有一些不属于状态机但是必要的部分,例如角色控制的参数、角色的消息机制和角色实体类等。那么综上所述,我们明确了基于角色控制的状态机应该包括角色状态类、角色状态转换路径类、角色状态机类和角色状态执行逻辑类四个部分。

3.需求

        接下来较为复杂的就是设计这四个类中具体的方法,这首先需要我们明确角色控制的需求,基于需求去设计才能尽可能避免偏离实际。

组成部分

必要属性

可选属性

必要方法

可选方法

角色状态

状态名称、状态优先级、角色控制参数、动画组件或系统、输入检测集合

未知

初始化方法、动画播放方法、重置方法

未知

角色状态转换路径

源状态、目标状态、状态机、角色控制参数

未知

初始化方法、重置方法

未知

角色状态机

未知

未知

初始化方法、重置方法

未知

角色状态执行逻辑

角色控制参数

未知

刷新方法、初始化方法、重置方法

未知

        角色状态最基本的功能需求是记录角色各个状态的信息,例如状态名称和状态优先级等,与角色状态对应的动画播放是采用Unity3D的Animator或Animation组件还是自定义的动画系统,这也可以作为角色状态的一部分,在角色状态中可能需要调用一些角色控制的参数,那么角色状态中还需要维护一个相关的变量,同时并非所有输入都需要在当前角色状态进行检测,例如角色跳跃的时候不一定需要检测攻击的输入,所以可以在角色状态中规定需要检测或不可检测的输入。除此之外角色状态还可以配备重置方法、初始化方法、动画播放的方法等。

        角色状态转换路径需要记录源状态到目标状态的转换信息和状态转换的检测逻辑,如果需要调用状态机或角色控制参数就加上对应的变量即可,还可以配置初始化方法、重置方法等。

        角色状态机需要管理各个角色状态和角色状态转换路径,向外提供调用接口,同时也可以配置初始化方法、重置方法等。角色状态机应该继承自基本的状态机,所以角色状态机中仅需要添加或重写一些特有的方法即可,具体的方法根据角色状态机的需求进行添加。

        角色状态执行逻辑用于记录某个角色状态的执行逻辑,例如与某些组件一起完成当前状态的角色控制的实现或者当前状态下某些角色控制参数的改变,可以配备刷新的方法、初始化的方法以及重置方法等。

        对于首次开发,我们无法非常完整地确定需求,所以我们可以边开发边改进,后续通过不断地优化来完善这个基于角色控制的状态机。

4.设计

        基于上述需求,基于角色控制的状态机分为角色状态、角色状态机、角色状态转换路径以及角色状态执行逻辑,四个部分分别对应PlayerState类、PlayerStateMachine类、PlayerStateTransition类以及PlayerStateRule类,且四个类分别继承自CSFState类、CSFStateMachine类、CSFStateTransition类以及CSFStateRule类。而对于PlayerState、PlayerStateMachine、PlayerStateTransition以及PlayerStateRule四个类具体的设计则需要根据角色控制的具体需求去完成,在接下来的实际示例UML图中可以看到对于这四个部分的具体类设计。

       我们可以先结合每个部分的功能来明确一些对应的属性和方法,然后逐渐修改完善,不断贴合需求进行优化。

实际示例(UML)

        如图1所示,AnimationEvents是属于动画事件类,用于管理角色各个状态的动画中的事件。PlayerState是角色状态类,继承自CSFState这个通用状态类。PlayerStateMachine是角色状态机类,继承自CSFStateMachine这个通用状态机类。PlayerStateTransition是角色状态转换路径类,继承自CSFStateTransition这个通用状态转换路径类。PlayerStateRule是角色状态执行逻辑类,继承自CSFStateRule这个通用状态执行逻辑类。PlayerTransitionMediator是角色状态转换路径中介者类,继承自CSFTransitionMediator这个通用状态转换路径中介者类,这个中介者类负责某个状态对应的所有状态转换路径的过渡检测。

        实际运转则是首先调用PlayerStateMachine中的Init方法对所有的PlayerState、PlayerStateTransition以及PlayerStateRule进行初始化,为每个PlayerState设置输入配置以及添加对应的PlayerStateRule,为每个PlayerState对应的PlayerTransitionMediator添加对应的PlayerStateTransition,最后将所有的PlayerState和PlayerStateTransition添加到PlayerStateMachine中,然后设置PlayerStateMachine的初始状态。

        每个PlayerState都具备一个OnEnter、OnUpdate和OnExit方法,在角色控制类中分别调用PlayerStateMachine的接口方法StateUpdate和StateRuleUpdate,StateUpdate方法负责PlayerStateMachine中当前状态对应的OnUpdate方法的执行,当前状态的OnUpdate方法中执行PlayerTransitionMediator中的StateCheck方法用于对当前状态对应的PlayerStateTransition的过渡进行检测,由于这个示例我们借助Animator播放动画,所以对应状态的动画播放则放在了OnEnter方法中执行,PlayerTransitionMediator中的StateCheck方法则是对每个PlayerStateTransition的按照优先级进行排序,优先级高的先进行检测,这个过渡检测的逻辑则对应着PlayerStateTransition中的CanTransitionTo方法,若通过了过渡检测,则PlayerStateMachine的当前状态将过渡到指定的状态,然后继续重复上述过程,在每一次StateUpdate方法执行后都会执行一次StateRuleUpdate方法,StateRuleUpdate负责当前状态的PlayerStateRule中的Update方法的调用,进而完成对应的角色状态执行逻辑的工作。每个状态都配置着一个PlayerState、PlayerStateTransition、PlayerStateRule和PlayerTransitionMediator的派生类,在这些派生类中只需要完成对应功能具体逻辑的编写即可,不需要关注各自之间的合作和调用问题。

图1

  

如果这篇文章对你有帮助,请给作者点个赞吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/934701.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI项目四:基于mediapipe的钢铁侠操作(虚拟拖拽)

若该文为原创文章,转载请注明原文出处。 一、介绍 在B站看到使用CVZone进行虚拟物体拖放,模仿钢铁侠电影里的程序操作!_哔哩哔哩_bilibili 是使用CVZone方式实现的,代码教程来源https://www.computervision.zone,感兴趣可以测试…

MathType7.4mac最新版本数学公式编辑器安装教程

MathType7.4中文版是一款功能强大且易于使用的公式编辑器。该软件可与word软件配合使用,有效提高了教学人员的工作效率,避免了一些数学符号和公式无法在word中输入的麻烦。新版MathType7.4启用了全新的LOGO,带来了更多对数学符号和公式的支持…

全国自考02325《计算机系统结构》历年真题试卷及答案 年份:202304

2023 年4 月高等教育自学考试全国统一命题考试 计算机系统结构试题答案及评分参考 (课程代码 02325) 一、选择题:本大题共 10小题,每小题1分 1.D 2.B 3.D 4.A 5.B 6.C 7.D 8.D 9. A 10.C 二、填空题:本大题共 10小题&#xff…

如何加入微信群?微信加群教程,如何加更多的群聊?

微信群是人们交流互动的重要平台之一,加入合适的微信群可以拓宽人脉、获取信息和分享经验。下面小编将分享三个方法,帮助你轻松加入心仪的微信群。 方法一:扫描二维码加入 很多微信群会设置专属的二维码,方便他人加入。当你得到某…

Linux操作系统--shell编程(条件判断)

(1).基本的语法 test condition [ condition ] 注意condition前后要有空格;在使用该种表达式的时候,条件非空即为 true,[ hello ]返回 true,[ ] 返回 false。我们可以通过echo $?来判断上一次执行的情况来判断真假(0真1假)。

详解预处理

全文目录 前言预定义符号#define 定义标识符常量#define 定义宏#define 替换规则# 宏参数转换字符串## 宏参数拼接带有副作用的宏参数 宏与函数的对比#undef 移出宏定义命令行定义条件编译#include 文件包含头文件的包含方式头文件的重复包含 前言 前面我们学习了程序的编译和…

【C语言基础】源文件与头文件详解

📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…

Office Tool Plus 使用与激活

Office Tool Plus 一个强大且实用的 Office 部署工具。 可以免费激活使用office各种版本 体验了一下,觉得很不错,我介绍一下我使用的方式: 1.安装软件 访问官网:Office Tool Plus 选择ZIP的包,下载后解压&#xff0c…

Huggingface托管机器学习模型及API提供

推荐:用 NSDT编辑器 快速搭建可编程3D场景 我想在我的网络和移动应用程序中使用机器学习模型,但要做到这一点,我必须在某个地方托管我的机器学习应用程序。 托管预先训练的 ML 模型称为推理。 我只想添加一些 Python ML 代码并快速获得 REST…

一段简单的汇编语言源程序【2】

此文章主要记录代码的编写,编译,连接,调试过程,相关工具的安装和使用介绍在前面的文章中已提供。 主要功能通过栈实现两个数的交换 源代码如下: assume cs:codesg codesg segmentmov ax,2000Hmov ss,axmov sp,0add s…

国产发力,长存入局|相变存储器PCM是SCM的未来吗?

在去年7月份有一件震惊存储圈的事情,那就是Intel说要放弃Optane产品线,包括PMEM和SSD两个方向都要放弃。存储圈看到听到这个消息也是一脸的茫然。 在Optane产品发布之前,大家针对DRAM和SSD之间的性能gap一直在苦苦找寻合适的产品。SCM存储级内…

深度学习12:胶囊神经网络

目录 研究动机 CNN的缺陷 逆图形法 胶囊网络优点 胶囊网络缺点 研究内容 胶囊是什么 囊间动态路由算法 整体框架 编码器 损失函数 解码器 传统CNN存在着缺陷(下面会详细说明),如何解决CNN的不足,Hinton提出了一种对于图…

一篇掌握BFD技术(二):OSPF与BFD联动配置

1. 实验目的 熟悉OSPF与BFD联动的应用场景掌握OSPF与BFD联动的配置方法 想要华为数通配套实验拓扑和配置笔记的朋友们点赞关注&#xff0c;评论区留下邮箱发给你&#xff01; 2. 实验拓扑 3. 实验步骤 1&#xff09;IP地址的配置 AR1的配置 <Huawei>system-view…

Origin软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 Origin是一款专业的科学绘图和数据分析软件&#xff0c;由美国OriginLab公司开发。它提供了丰富的数据分析和绘图工具&#xff0c;适用于各种科学领域&#xff0c;如生物学、化学、物理学、医学、地球科学等。Origin软件的主要特…

使用 S3 生命周期精确管理对象生命周期

在亚马逊工作这些年,我发现 S3 的生命周期配置是管理对象生命周期的重要但复杂的工具。在这篇文章中,我将利用实战经验,深入剖析生命周期,从核心概念到实际应用。 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活…

C语言暑假刷题冲刺篇——day5

目录 一、选择题 二、编程题 &#x1f388;个人主页&#xff1a;库库的里昂 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;C语言每日一练✨相关专栏&#xff1a;代码小游戏、C语言初阶、C语言进阶&#x1f91d;希望作者…

程序的编译链接【编译链接大概步骤】

全文目录 &#x1f600; 前言&#x1f642; 翻译环境和执行环境&#x1f636; 编译和链接&#x1f635;‍&#x1f4ab; 预编译&#xff08;预处理&#xff09;&#x1f635;‍&#x1f4ab; 编译&#x1f635;‍&#x1f4ab; 汇编&#x1f635;‍&#x1f4ab; 链接 &#x1…

数值类特征

数值类特征 数值类特征是最常见的一种特征类型&#xff0c;数值可以直接喂给算法。 为了提升效果&#xff0c;我们需要对数值特征做一些处理&#xff0c;本文介绍了4种常见的处理方式&#xff1a;缺失值处理、二值化、分桶、缩放。 什么是数值类特征&#xff1f; 数值类特征就是…

腾讯云服务器地域和可用区详细介绍_选择攻略

腾讯云服务器地域有什么区别&#xff1f;怎么选择比较好&#xff1f;地域选择就近原则&#xff0c;距离地域越近网络延迟越低&#xff0c;速度越快。关于地域的选择还有很多因素&#xff0c;地域节点选择还要考虑到网络延迟速度方面、内网连接、是否需要备案、不同地域价格因素…

Redis数据类型全总结【超详细万字总结】

文章目录 前言一、String1、内部实现2、应用场景缓存对象常规计数分布式锁共享 Session 信息 3、常用指令 二、List1、内部实现2、应用场景消息队列List 作为消息队列有什么缺陷 3、常用指令 三、Hash1、内部实现2、应用场景缓存对象购物车 3、常用指令 四、Set1、内部实现2、应…