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的状态机系统是一个强大的动画控制工具:
- 提供可视化的状态管理
- 支持复杂的动画过渡
- 可通过代码灵活控制
- 子状态机提供更好的组织方式
在实际开发中,应当:
- 合理规划状态机结构
- 善用子状态机降低复杂度
- 注意性能优化
- 保持良好的代码实践