Unity2D - 状态机(State Machine)详解

news2024/12/29 10:10:04

1. 状态机概述

在角色的生成中,由于事件的不同,动作的不同,角色会处于不同的状态中。例如对战冒险游戏,面临Boss的攻击,角色会受到例如中毒,恐惧等Debuff效果,若单纯的在一个脚本中使用if等语句进行事件处理,往往会比较冗杂,程序出现bug后也无法及时排查出问题。

状态机此时就是一个很好解决上述问题的方式。例如在玩家移动过程中,此时的状态为移动状态。设定好不同状态之后。只需要相应的判定条件即可进入状态执行对应事件。

2. 初始化状态机

2.1. PlayerStateMachine

public class PlayerStateMachine : MonoBehavior
{
    public PlayerState currentState {get; privet set;} //申明一个状态
    
    public void Initialize(PlayerState _startState)
    {
        currentState = _startState; //初始化状态
        currentState.Enter(); //进入状态
    }

    public void ChangeState(PlayerState _newState)
    {
        currentState.Exit(); // 退出当前状态
        currentState = _newState;
        currentState.Enter();
    }
}

定义PlayerStateMachine类的作用类似于一个机器,将player的各个状态进行调配,例如状态机所含Initialize方法初始化状态,以及改变当前状态。

在改变当前状态时,先要执行状态中的Exit()方法,为后续动作增加了更大的可能性。

2.2. PlayerState

public class PlayerState
{
    protected PlayerStateMachine stateMachine;
    protected Player player; 
    protected string animatorName;

    public PlayerState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) //   构造函数,将上述变量传入
    {
        this.player = _player; //获取player,也可以调用player中的参数    
        this.stateMachine = _stateMachine;
        this.animatorName = _animBoolName; //动画参数的名字
    }

    public virtual void Enter()
    {
        rb = player.rb;
        player.anim.SetBool(animatorName,true);
    }

    public virtual void Update()
    {
        xInput = Input.GetAxisRaw("Horizontal"); //任意状态都可以持续调用
    }

    public virtual void Exit()
    {
        player.anim.SetBool(animatorName,false); //退出当前状态时,将动画参数设置为false
    }

}

与其说PlayerState是各个状态的模板,更不如说是各状态共有的特征。简化了代码,各状态所需要的初始化在PlayerState类中以及设定好了,在后续编写状态代码时只需简单的base.Update();即可。

在父类状态中想要一直持续调用的事件,在后续也可以传导给子类状态,例如想要一直获取角色在水平轴上的Input.GetAxisRaw。通过继承的方式,子类无论在何种状态,都在持续调用这段代码。

2.3. Player

public class Player: MonoBehaviour
{
    //声明组件以及所需要的状态
    public Rigidbody2D rb {get;private set;}
    public Animator anim {get;private set;}

    public PlayerStateMachine stateMachine {get;private set}
    public PlayerIdleState idleState {get;private set}

    private void Awake()   //初始化该player所拥有的状态与状态机,在实例化对象之前加载
    {
        stateMachine = new PlayerStateMachine();
        idleState = new PlayerIdleState(this,StateMachine,"Idle");
    }

    private void Start()
    {
        anim = GetComponentInChildren<Animator>();
        rb = GetComponent<Rigidbody2D>();
        StateMachine.Initialize(idleState); #初始化idle状态
    }

    private void Update()
    {
        StateMachine.currentState.Update(); //通过player的持续调用,持续调用当前状态的Update
    }
}

Player是应用的我们角色的脚本,实现为player声明好对应的状态机,更好的去初始化与改变当前状态。

通过Unity引擎自带的Update方法,进一步实现每个状态中我们所编写的Update方法。

3. 状态机的应用

3.1. Idle状态

public class PlayerIdleState : PlayerGroundedState
{
    public PlayerIdleState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
    {
    }

    public override void Enter()
    {
        base.Enter();
    }

    public override void Exit()
    {
        base.Exit();
    }

    public override void Update() //持续调用
    {
        base.Update();
        if (xInput != 0)
        {
            stateMachine.ChangeState(player.moveState);
        }
    }
}

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

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

相关文章

Linux Swap

Swap: 页面换出&#xff1a;就是在 Swap 机制下&#xff0c;当内存资源紧张时&#xff0c;内核就会把不经常使用的这些匿名页中的数据写入到 Swap 分区或者 Swap 文件中。从而释放这些数据所占用的内存空间。 页面换入&#xff1a;就是当进程再次访问那些被换出的数据时&…

中医对于帕金森病的病因和症状有何解释?

中医对帕金森病的病因解释 中医认为帕金森病的病因复杂多样&#xff0c;涉及多个方面。首先&#xff0c;精神因素如长期的情绪抑郁、悲伤、忧虑等精神不畅可能导致气机郁结&#xff0c;气血运行障碍&#xff0c;进而影响脑部神经系统的功能。其次&#xff0c;肝郁气滞也被认为…

怎么把amr格式转换为mp3格式?这6个mp3格式转换方法不容错过!

怎么把amr格式转换为mp3格式&#xff1f;AMR&#xff08;自适应多速率&#xff09;是一种音频编码格式&#xff0c;通常用于存储基于语音的文件&#xff0c;例如语音记录和VoIP应用&#xff0c;在3G移动设备上使用。它具有非常高的压缩比&#xff0c;导致声音质量较差。早期的安…

【Python机器学习】分类向量——数字可以编码分类变量

在adult数据集的例子中&#xff0c;分类变量被编码为字符。一方面可能会有拼写错误&#xff0c;但另一方面&#xff0c;它明确的将一个变量标记为分类变量。无论是为了便于存储还是因为数据的手机方式&#xff0c;分类变量通常被编码为整数。 假设adult数据集中的人口普查数据…

使用shell脚本编写监控系统资源(CPU,内存,磁盘)使用情况

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f6e0;️Shell编程专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年6月20日16点30分 &#x1f004;️文章质量&#xff1a;95分 目录 ————前言———— 1.本章目标 2.编写脚本 1.获取内…

Go 中使用map时注意的问题

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

uniapp uniCloud云开发

uniCloud概述 uniCloud 是 DCloud 联合阿里云、腾讯云、支付宝云&#xff0c;为开发者提供的基于 serverless 模式和 js 编程的云开发平台。 uniCloud 的 web控制台地址&#xff1a;https://unicloud.dcloud.net.cn 文档&#xff1a;https://doc.dcloud.net.cn/uniCloud/ un…

AI绘画:P图如此丝滑,OpenAI上线ChatGPT图像编辑功能,DallE-3绘画如此简单

大家好我是极客菌&#xff0c;用ChatGPT的DallE-3进行AI绘画对很多人来说是一个门槛很低的选择&#xff0c;现在OpenAI又重磅上线了图像编辑器功能(DallE editor)&#xff0c;可以很方便的对图片的局部进行修改&#xff0c;而且支持中文&#xff0c;主打一个功能强大且好用&…

论文学习——一种自适应提升的动态多目标优化进化算法

论文题目&#xff1a;A dynamic multi-objective optimization evolutionary algorithm with adaptive boosting 一种自适应提升的动态多目标优化进化算法&#xff08;Hu Peng a,b,∗, Jianpeng Xiong a, Chen Pi a, Xinyu Zhou c, Zhijian Wu d&#xff09;IEEE Swarm and Ev…

FreeSWITCH 1.10.10 简单图形化界面24-呼入呼出编码

FreeSWITCH 1.10.10 简单图形化界面24-呼入呼出编码 FreeSWITCH GUI界面预览00、安装FreeSWITCH GUI先看使用手册1、语音接听还是视频接听2、排查 FreeSWITCH GUI界面预览 http://myfs.f3322.net:8020/ 用户名&#xff1a;admin&#xff0c;密码&#xff1a;admin FreeSWITCH…

MySQL之如何定位慢查询

1、如何定位慢查询 1.1、使用开源工具 调试工具&#xff1a;Arthas 运维工具&#xff1a;Promethuss、Skywalking 1.2、MySQL自带慢日志 慢查询日志记录了所有执行时间超过指定参数&#xff08;long_query_time&#xff0c;单位&#xff1a;秒&#xff0c;默认10秒&#x…

The difference between Manhattan distance and Cosine Distance

题意&#xff1a;为什么即使返回了相同的文本块&#xff0c;曼哈顿距离&#xff08;Manhattan Distance&#xff09;和余弦距离&#xff08;Cosine Distance&#xff09;之间还是存在差异&#xff1f; 问题背景&#xff1a; I am using the qdrant DB and client for embeddin…

探索LangChain-Chatchat 0.3:一体化Agent与强大RAG模型的全面入门指南

介绍 LangChain-Chatchat 支持RAG和Agent0.3版本跟大模型解耦,支持Xinference、Ollama、LocalAI、FastChat、One API,可以非常方便的切换各个模型,本文只是介绍XinferenceXorbits Inference (Xinference) 是一个开源平台&#xff0c;用于简化各种 AI 模型的运行和集成。借助 X…

论文辅导 | 基于贝叶斯优化-卷积神经网络-双向长短期记忆神经网络的锂电池健康状态评估

辅导文章 模型描述 准确估计电池健康状态是设备稳定运行的关键。针对当前健康状态研究中容量难以直接测量、估计模型调参费时等问题&#xff0c;提出基于多健康特征的贝叶斯优化&#xff08;BO&#xff09;算法优化卷积神经网络&#xff08;CNN&#xff09;与双向长短期记忆&a…

气膜仓库的优势与应用—轻空间

随着现代物流和存储需求的不断增长&#xff0c;传统仓库的建设和运营成本日益增加&#xff0c;企业需要寻找更加灵活、高效和经济的解决方案。在这种背景下&#xff0c;气膜仓库作为一种新型仓储形式&#xff0c;以其独特的优势和广泛的应用前景&#xff0c;逐渐受到市场的青睐…

视频号视频怎么保存到手机,视频号视频怎么保存到手机相册里,苹果手机电脑都可以用

随着数字媒体的蓬勃发展&#xff0c;视频已成为我们日常生活中不可或缺的一部分。视频号作为众多视频分享平台中的一员&#xff0c;吸引了大量用户上传和分享各类精彩视频。然而&#xff0c;有时我们可能希望将视频号上的视频下载下来,以下将详细介绍如何将视频号的视频。 方法…

自养号测评助力:亚马逊、沃尔玛电商高效测评补单技巧,轻松实现销量与补单双赢

要在竞争激烈的市场中通过测评补单的方式提升产品权重和销售&#xff0c;构建一个稳定且高效的测评补单系统至关重要。通过精心培养一批高质量的买家账号&#xff0c;并深入了解真实买家的行为数据&#xff0c;结合对风控数据的精准把控&#xff0c;我们能够自主推动推广进程&a…

shell:处理命令行参数 获取用户输入

1. 命令行参数 1.1 位置参数 bash shell会将一些称为位置参数(positional parameter)的特殊变量分配给输入到命令行中的 所有参数。这也包括shell所执行的脚本名称。位置参数变量是标准的数字:$0是程序名&#xff0c;$1是第 一个参数&#xff0c;$2是第二个参数&#xff0c;依…

【LLM 评估】MMLU benchmark:用于衡量 LM 的多任务语言理解能力

论文&#xff1a;Measuring Massive Multitask Language Understanding ⭐⭐⭐⭐ ICLR 2021, arXiv:2009.03300 Code: GitHub 论文速读 本文提出了一个 benchmark&#xff1a;MMLU&#xff0c;一个覆盖了 57 个 subjects 的多项选择题的数据集。 数据集的 question 数量&…

SpringBoot-SpringBoot中文文档

简介 Spring Boot是由Pivotal团队提供的一套开源框架&#xff0c;可以简化spring应用的创建及部署。它提供了丰富的Spring模块化支持&#xff0c;可以帮助开发者更轻松快捷地构建出企业级应用。Spring Boot通过自动配置功能&#xff0c;降低了复杂性&#xff0c;同时支持基于J…