Unity状态机相关

Unity状态机(Animator)详解

一、基本概念

1. 什么是状态机

  • 用于管理动画状态的系统
  • 控制角色/物体的不同状态切换
  • 基于条件驱动的状态转换
  • 可视化的动画编程工具

2. Animator组件

  • Unity内置的动画控制器组件
  • 连接状态机和游戏对象
  • 管理动画权重和过渡
  • 支持多层动画混合

二、Animator Window主要组成

1. Parameters(参数面板)

  • 类型

    • Int:整数类型
    • Float:浮点数类型
    • Bool:布尔类型
    • Trigger:触发器类型
  • 使用场景

    • 控制状态转换
    • 动画混合权重
    • 脚本交互
    • 条件判断

2. Layers(层级面板)

  • Base Layer:基础层,默认层
  • Additional Layers:额外层,用于动画混合
  • Weight:层级权重设置
  • Mask:动画遮罩设置
  • Blending:混合模式设置
    • Override:覆盖
    • Additive:叠加

3. States(状态节点)

  • Entry:入口节点
  • Any State:任意状态
  • Exit:退出节点
  • Motion:动画状态
  • Sub-State Machine:子状态机

三、状态机功能详解

1. 状态设置

Motion状态属性:
- Speed:播放速度
- Motion:动画片段
- Transitions:转换条件
- Mirror:镜像设置
- Cycle Offset:循环偏移
- Foot IK:脚部IK
- Write Defaults:默认值写入

2. 转换设置

Transition属性:
- Has Exit Time:是否有退出时间
- Exit Time:退出时间点
- Transition Duration:过渡持续时间
- Transition Offset:过渡偏移
- Interruption Source:中断源

3. 混合树(Blend Tree)

混合类型:
- 1D Blend:一维混合
- 2D Simple Directional:二维简单方向
- 2D Freeform Directional:二维自由方向
- 2D Freeform Cartesian:二维笛卡尔
- Direct:直接混合

四、子状态机(Sub-State Machine)

1. 基本概念

  • 状态机中的状态机
  • 用于组织复杂的状态逻辑
  • 提高状态机的可读性
  • 支持状态复用

2. 创建和使用

创建步骤:
1. 右键空白处
2. 选择Create Sub-State Machine
3. 命名子状态机
4. 双击进入编辑

3. 特点和优势

  • 状态分组管理
  • 逻辑模块化
  • 降低复杂度
  • 便于维护

五、实际应用示例

1. 角色控制器

// 状态切换示例
public class PlayerController : MonoBehaviour
{
    
    
    private Animator animator;
    
    void Start()
    {
    
    
        animator = GetComponent<Animator>();
    }
    
    void Update()
    {
    
    
        // 行走状态
        animator.SetFloat("Speed", Input.GetAxis("Vertical"));
        
        // 跳跃状态
        if(Input.GetButtonDown("Jump"))
        {
    
    
            animator.SetTrigger("Jump");
        }
        
        // 攻击状态
        if(Input.GetMouseButtonDown(0))
        {
    
    
            animator.SetTrigger("Attack");
        }
    }
}

2. 状态机结构示例

PlayerAnimator
├── Base Layer
│   ├── Idle
│   ├── Movement
│   │   ├── Walk
│   │   └── Run
│   ├── Combat
│   │   ├── Attack1
│   │   ├── Attack2
│   │   └── Attack3
│   └── Actions
│       ├── Jump
│       └── Roll
└── Upper Body Layer
    └── Combat
        ├── Aim
        └── Shoot

六、高级功能

1. 状态机行为(StateMachineBehaviour)

public class CustomBehaviour : StateMachineBehaviour
{
    
    
    // 状态进入时
    override public void OnStateEnter(...)
    {
    
    
        // 初始化逻辑
    }
    
    // 状态更新时
    override public void OnStateUpdate(...)
    {
    
    
        // 更新逻辑
    }
    
    // 状态退出时
    override public void OnStateExit(...)
    {
    
    
        // 清理逻辑
    }
}

2. 动画事件

public class AnimationEvents : MonoBehaviour
{
    
    
    // 在动画帧上调用
    public void OnFootstep()
    {
    
    
        PlayFootstepSound();
    }
    
    // 攻击判定
    public void OnAttackPoint()
    {
    
    
        CheckAttackCollision();
    }
}

七、性能优化建议

1. 状态机优化

  • 减少不必要的状态
  • 合理使用子状态机
  • 优化转换条件
  • 控制层级数量

2. 动画优化

  • 合理设置帧率
  • 使用动画压缩
  • 适当的过渡时间
  • 避免过多的动画事件

3. 代码优化

// 缓存参数ID
private readonly int speedHash = Animator.StringToHash("Speed");
private readonly int jumpHash = Animator.StringToHash("Jump");

void Update()
{
    
    
    // 使用Hash值而不是字符串
    animator.SetFloat(speedHash, currentSpeed);
    animator.SetTrigger(jumpHash);
}

八、最佳实践

1. 状态机组织

  • 合理划分状态
  • 使用子状态机组织复杂逻辑
  • 清晰的状态命名
  • 合理的层级结构

2. 参数管理

  • 统一的命名规范
  • 合理的参数类型选择
  • 必要的默认值设置
  • 文档化参数用途

3. 转换逻辑

  • 明确的转换条件
  • 合适的过渡时间
  • 避免状态循环
  • 处理中断情况

总结

Unity的状态机系统是一个强大的动画控制工具:

  1. 提供可视化的状态管理
  2. 支持复杂的动画过渡
  3. 可通过代码灵活控制
  4. 子状态机提供更好的组织方式

在实际开发中,应当:

  • 合理规划状态机结构
  • 善用子状态机降低复杂度
  • 注意性能优化
  • 保持良好的代码实践