Unity状态机的实现方法一

devtools/2025/2/19 9:16:37/

Unity状态机知识点整理

1. 状态机基本概念

1.1 什么是状态机

Unity常见的状态机管理分为三种:

  1. 枚举状态机
  2. 通过实现接口的方式多态出的更加便于维护的状态机
  3. Unity Animator自带的StateMachineBehaviour

1.2 不同状态机实现方式的对比

自定义状态机(枚举/接口)特点:
  1. 控制灵活度

    • 完全自主控制状态转换逻辑
    • 可以方便地访问和修改游戏对象的任何组件
    • 能够实现复杂的状态嵌套和组合
  2. 性能优势

    • 代码执行效率高
    • 内存占用小
    • 可以精确控制状态检查的频率
  3. 调试便利性

    • 可以方便地添加调试信息
    • 状态切换逻辑清晰可见
    • 便于断点调试
  4. 使用场景

    • 适合复杂的游戏逻辑控制
    • 需要频繁状态切换的情况
    • 需要与其他系统紧密集成的情况
StateMachineBehaviour特点:
  1. 可视化优势

    • 在Animator窗口中可视化编辑
    • 状态转换条件直观显示
    • 便于美术和策划理解和配置
  2. 动画集成

    • 与动画系统紧密结合
    • 自动处理动画过渡
    • 内置动画事件支持
  3. 局限性

    • 状态逻辑需要通过特定的回调函数实现
    • 访问其他组件相对繁琐
    • 不适合处理复杂的游戏逻辑
  4. 使用场景

    • 主要用于动画状态控制
    • 简单的行为状态切换
    • 需要可视化编辑的情况

1.3 StateMachineBehaviour示例

public class PlayerRunBehavior : StateMachineBehaviour
{// 状态进入时调用override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex){// 初始化逻辑}// 状态更新时调用override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex){// 更新逻辑}// 状态退出时调用override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex){// 清理逻辑}
}

1.4 选择建议

  1. 使用自定义状态机当:

    • 需要处理复杂的游戏逻辑
    • 需要高性能和精确控制
    • 状态之间有复杂的数据传递
    • 需要与多个系统交互
  2. 使用StateMachineBehaviour当:

    • 主要处理动画相关的状态
    • 需要可视化编辑状态流程
    • 团队中有非程序人员需要配置状态
    • 状态逻辑相对简单

2. 脚本中的状态机实现分析

2.1 状态定义

protected enum State
{Normal,  // 普通状态Attack   // 攻击状态
}
protected State currentState;  // 当前状态

2.2 状态初始化

protected virtual void Awake()
{controller = GetComponent<CharacterController>();animator = GetComponent<Animator>();currentState = State.Normal;  // 初始化为普通状态
}

2.3 状态切换机制

protected void ChangeState(State state)
{// 退出当前状态switch(currentState){case State.Normal:break;case State.Attack:break;}// 进入新状态switch(state){case State.Normal:break;case State.Attack:animator.SetTrigger("Attack");  // 触发攻击动画break;}currentState = state;  // 更新当前状态
}

3. 枚举状态机的优势

3.1 代码组织优势

  • 结构清晰:每个状态的行为被清晰地划分
  • 易于维护:添加新状态只需扩展枚举和相应的处理逻辑
  • 代码复用:状态逻辑可以被多个角色类继承和复用

3.2 游戏逻辑优势

  • 状态隔离:不同状态的行为互不干扰
  • 转换控制:可以严格控制状态间的转换条件
  • 动画整合:便于与动画系统集成(如示例中的animator)

4. 使用流程

  1. 定义状态

    • 使用enum定义可能的状态
    • 声明当前状态变量
  2. 初始化

    • 在Awake或Start中设置初始状态
    • 获取必要的组件引用
  3. 状态切换

    • 实现状态切换方法
    • 处理退出当前状态的逻辑
    • 处理进入新状态的逻辑
    • 更新状态标记
  4. 状态更新

    • 在Update等生命周期方法中根据当前状态执行相应逻辑
    • 通过HandleMovement等抽象方法实现具体行为

5. 扩展建议

5.1 状态扩展示例

protected enum State
{Normal,Attack,Jump,    // 可添加跳跃状态Hurt     // 可添加受伤状态
}

5.2 功能扩展方向

  1. 状态参数

    • 可以为每个状态添加参数配置
    • 使用ScriptableObject存储状态配置
  2. 状态持续时间

    • 可以添加状态持续时间控制
    • 实现状态自动切换机制
  3. 状态嵌套

    • 可以实现状态的层级结构
    • 支持子状态机的实现

6. 注意事项

  1. 状态切换的原子性

    • 确保状态切换过程是完整的
    • 避免状态切换过程中的中断
  2. 性能考虑

    • 避免频繁的状态切换
    • 合理控制状态数量
  3. 代码维护

    • 保持状态逻辑的独立性
    • 做好状态切换的条件管理
    • 适当的注释和文档说明

以上是Unity两种状态机的实现方式,更便于维护的状态机是枚举状态机,此内容会在后续的投稿中更新!!!!!


http://www.ppmy.cn/devtools/158702.html

相关文章

Ubuntu 上安装和配置 Nexus Repository Manager

在 Ubuntu 上安装和配置 Nexus Repository Manager&#xff08;Sonatype Nexus&#xff09;通常用于管理 Maven、npm、Docker 等包的私有仓库。以下是详细步骤&#xff1a; 1. 系统准备 更新系统并安装必要依赖&#xff1a; 在终端运行以下命令&#xff1a; sudo apt update…

LabVIEW用户界面(UI)和用户体验(UX)设计

作为一名 LabVIEW 开发者&#xff0c;满足功能需求、保障使用便捷与灵活只是基础要求。在如今这个用户体验至上的时代&#xff0c;为 LabVIEW 应用程序设计直观且具有美学感的界面&#xff0c;同样是不容忽视的关键任务。一个优秀的界面设计&#xff0c;不仅能提升用户对程序的…

deepin linux UOS AI 使用 deepseek-r1 30B

我们用 ollama 下载 deepseek-r1 3B 执行命令: $ ollama pull models/unsloth/DeepSeek-R1-Distill-Qwen-32B-GGUF 下载完成后 我们就要重新更改目录和文件了 deepseek-r1/gguf (这是目录结构) 然后我把 gguf文件 更名成 DeepSeek-R1.gguf (就是目录下最大的那个文件) …

springCloud-2021.0.9 之 GateWay 示例

文章目录 前言springCloud-2021.0.9 之 GateWay 示例1. GateWay 官网2. GateWay 三个关键名称3. GateWay 工作原理的高级概述4. 示例4.1. POM4.2. 启动类4.3. 过滤器4.4. 配置 5. 启动/测试 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收…

2025年智慧城市解决方案下载:AI-超脑中台,体系架构整体设计

2025年&#xff0c;随着人工智能、物联网、大数据等新兴技术的深度融合&#xff0c;智慧城市解决方案正迈向更高层次的智能化和协同化阶段。其中&#xff0c;AI-超脑中台作为核心架构的一部分&#xff0c;为城市智能化运行提供了强大支撑。 智慧城市最新解决方案&#xff0c;标…

vue2中 computed 计算属性

文章目录 vue2中 computed 计算属性1. 什么是计算属性&#xff1f;2. 基本用法1. 定义计算属性2. 计算属性的缓存特性 3. 计算属性的高级用法1. 计算属性的 Getter 和 Setter 方法2. 计算属性的依赖追踪 4. 计算属性与方法的区别5. 实际应用案例1. 格式化数据2. 计算总价3. 动态…

用户态进程与内核态进程的区别详解

在 Linux 系统中&#xff0c;进程是操作系统最基本的运行单位&#xff0c;它们分为用户态进程&#xff08;User Mode Process&#xff09;和内核态进程&#xff08;Kernel Mode Process&#xff09;。这两种进程的运行环境、权限、职责和交互方式都有很大不同。对于初学者来说&…

Spring 事务及管理方式

Spring 事务管理是 Spring 框架的核心功能之一&#xff0c;它为开发者提供了一种方便、灵活且强大的方式来管理数据库事务。 1、事务的基本概念 事务是一组不可分割的操作序列&#xff0c;这些操作要么全部成功执行&#xff0c;要么全部失败回滚&#xff0c;以确保数据的一致…