主题
动画系统
工业级多层动画运行时:支持 N 层混合、骨骼遮罩、过渡策略、BlendTree、IK、MoLang 驱动和关键帧事件。
架构总览
多层动画
动画系统的核心是 层(Layer) 概念。每个层独立采样动画姿态,层间按优先级顺序混合:
AnimationLayer 结构
每个层包含以下属性:
| 属性 | 类型 | 说明 |
|---|---|---|
id | AnimationLayerId | 层唯一标识 |
player | AnimationTrackPlayer | 动画轨道播放器 |
blendMode | AnimationLayerBlendMode | 混合模式 |
weight | Double | 层权重 (0.0 ~ 1.0) |
mask | BedrockAnimationMask | 骨骼遮罩 |
blendTreeResolver | BlendTreeResolver | BlendTree 解析器 |
混合模式
| 模式 | 语义 | 典型用途 |
|---|---|---|
| Override | 完全替换低层姿态 | 主体动画(Idle、Walk、Run) |
| Additive | 在低层姿态基础上叠加 | 呼吸、受击抖动、表情 |
| Weighted | 按权重与低层混合 | 过渡中间态、部分覆盖 |
骨骼遮罩
BedrockAnimationMask 控制每个层影响哪些骨骼:
all()— 影响所有骨骼(默认)- 自定义遮罩 — 按骨骼名过滤,未命中的骨骼保持低层姿态
典型场景:上半身攻击动画不影响腿部行走,下半身行走不影响手臂挥砍。
过渡策略
层间过渡通过 AnimationLayerTransition 管理,支持 4 种模式:
| 过渡类型 | 触发时机 | 行为 |
|---|---|---|
NONE | 无过渡 | 立即切换 |
CLIP | 同层内动画切换 | 采样器内部插值(lerpIn/lerpOut) |
LAYER_ENTER | 层激活时 | 从低层姿态渐入当前层 |
LAYER_EXIT | 层退出时 | 从当前层渐出到低层姿态 |
过渡边界通过 resolveTransition(lowerPose) 解析,确保层组合顺序正确。
BlendTree
AnimationLayerBlendTreeResolver 允许单个层内混合多个动画:
默认解析器 single() 将播放状态包装为单节点树。自定义解析器可实现速度驱动的 Walk/Run 混合、方向混合等复杂逻辑。
动画采样
关键帧插值
动画数据以关键帧序列存储,运行时按当前时间采样:
- 支持多种缓动函数(Linear、CatmullRom、Step 等)
- 循环动画自动处理时间回绕
- 支持播放速度控制(
speed参数)
播放状态
AnimationPlaybackState 追踪每个动画的运行时状态:
| 状态 | 说明 |
|---|---|
| 播放中 | 正常采样推进 |
| 暂停 | 时间冻结 |
| 过渡中 | 正在 lerp 进入/退出 |
| 完成 | 非循环动画播放结束 |
优先级系统
服务端动画调度支持优先级:
- 高优先级动画覆盖低优先级
- 同优先级按
override模式决定是否替换 force标记可无视优先级强制播放
IK 运行时
反向运动学(Inverse Kinematics)在动画采样后应用:
- 基于骨架中定义的 IK 链
- 支持多关节链(链长度可配置)
- 目标位置由 Locator 或外部输入驱动
MoLang 驱动
动画关键帧值支持 MoLang 表达式:
- 运行时求值,支持实体状态查询
- 绑定上下文:实体位置、旋转、生命值、自定义变量等
- 用于程序化动画(如基于速度的倾斜角度)
关键帧事件
动画可在特定时间点触发事件:
- 事件在采样时检测并分发
- 支持声音、粒子、自定义回调
- 循环动画每次经过事件点都会触发