unity 内部接口协议_unity 给模型绑定骨骼


Animation Clip

Unity 的动画是基于所谓 Animation Clips 的概念,它记录了一些对象上的数据(比如坐标、旋转、透明度等等)的关键帧,然后插值获取每一帧的数据。Animation clips 可以通过导入第三方软件的导出动画获得,也可以在Unity中直接创建。第三方导入的 Animation Clip 是只读的,如果需要修改,则需要拷贝出另外的副本。

Animator Controllers

恰当的时机播放特殊的动画,比如角色站立时播放站立的动画,跑动时播放跑步动画,建筑静止时播放静止动画,升级时播放升级动画,并且还需要定义这些动画的切换过程,完成这些工作的就是 Animator Controller。具体而言,它是通过状态机的方式来实现上述需求。


unity 内部接口协议_unity 内部接口协议_02


它会将各个状态关联到 Animation Clip 上,可以使用代码直接切换状态,也可以通过修改各种预先设置好的参数(Parameters)来达到同样的目的。和 Animation Clip 一样,Animator Controller 也可以以 Asset 的形式被创建、编辑、保存。编辑获得想要的 Animator Controller 后,将其添加到 Animator 组件上即可在游戏中使用。

Animation 状态机

State

上文提到状态机中的每个状态都对应一个 Animation Clip,但是除了这些真正的动画状态之外,还有如下特殊状态

  • Enter,状态机的入口
  • Exit,状态机的出口
  • Any,代表任意状态

Transition

状态与状态之间存在转换的过程,Transition 即是用来描述这个过程,我们可以在这里定义状态之间的切换,比如切换的持续时间,从旧状态的哪一帧结束,新状态的哪一帧开始,从而实现各种业务需求以及表现的平滑过渡。此外可以启用 Mute 和 Solo来限制状态之间的切换,因为即使没有 Transition ,也可以强行从一个状态硬切换到另一个状态。

Animation Parameter

上面说到可以通过修改 Parameter 来达到切换状态的目的,Parameter 的值可以是整数、浮点数、布尔值或者Trigger(使用完后会被自动重置的布尔值),可以通过 Animator 提供的接口来修改它们。可以作为 Transition 的条件从而影响状态的切换。

State Machine Behaviours

可以为状态添加 State Machine Behaviours ,他提供了一些接口让我们可以在一些时机执行相应的逻辑,比如在状态退出的时候调用播放音频的接口。

Sub-State Machines

可以将多个状态组合一个 Sub-State Machines ,可以减轻 Animator 的维护成本。

Animation Layers

Unity 使用 Animation Layers 管理用于不同部分的状态机。不如下半身层管理走路、跳跃,上半身层负责投掷、射击。

可以通过调整层权重(Layers Widget)来管理动画中的层。点击 layer 右侧的齿轮。可以打开层的设置。


unity 内部接口协议_unity 内部接口协议_03


unity 内部接口协议_unity 内部接口协议_04


可以设置 Avatar mask(确定动画将会应用到模型的哪部分),Blending(和其他层的混合模式),Override 代表忽略其他层,Additive 代表会叠加到前面的层之上。此外,还可以通过 sync layer 实现状态机的复用, 一个 layer 可以通过与其他的 layer 同步从而共享被同步的 layer 的状态机。


unity 内部接口协议_unity 给模型绑定骨骼_05


Animator Override Controller

类似 Animator Controller,可以用来复用 Animator Controller 的状态机。它可以覆盖替换 Animator Controller 中的状态对应的 Animation Clip。

Avatar

我们可以在导入模型的时候,将骨骼关联到 Avatar 上,这个 Avatar 可以是导入模型时创建,也可以引用之前导入的,这个关联过程如果满足匹配的话就可以自动关联,否则就需要手动关联,Unity 允许部分骨骼关联。拥有 Avatar 可以使用 Unity 提供的目标匹配(Target Matching)、IK (Inverse Kinematics),重定向(Retargeting)等特性。

Blend Tree

混合不同的 motion 再游戏动画里是很常见的需求,比如根据角色速度混合走路和跑步动画,还有跑动时要混合跑步与转向动画。这时候就可以使用 Blend Tree 了。

状态机和 Blend Tree 都能实现不同动画间的平滑过渡,但是前者是基于两个状态的 transition,后者则可以是大于等于两个动画的混合。Blend Tree 本身也可以是状态机里的一个 state。当然这些动画的差距不能太大,毕竟线性插值也是有极限的。


unity 内部接口协议_unity 给模型绑定骨骼_06


Blend Tree 将会根据绑定的 Parameters 还有 Blend Type 来确定当前播放的动画。

1D Blending

1D Blending 通过单个参数来确定动画,它仅仅是简单在各个子树之间根据权重插值,看图就明白了。


unity 内部接口协议_unity 内部接口协议_07


蓝色锥形的高度代表权重,可以看出随参数的变换,各个动画的权重变化。这个权重的分配可以手动编辑,也可以靠 unity 自动完成。自动完成可以是均匀分配,也可以是根据动画的速度等参数加权分配。

2D Blending

2D Blending 通过两个参数来确定动画,本质多是通过两个值构成的向量获得在二维平面上各个位置的权重,不过各个类型之间还是有所区别的。


unity 内部接口协议_unity 内部接口协议_08


  • 2D Simple Directional,适用于动画代表不同方向的情况,比如向前后左右走,单个方向只允许有一个动画。
  • 2D Freeform Directional,也适用于动画代表不同方向的情况,但允许同向存在多个动画。
  • 2D Freeform Cartesian,适用于动画不代表不同方向的情况,参数可以用来描述方向之外的概念,比如角速度或者线性速度。

和 1D Blending 一样,各个动画的位置也可以通过设置自动计算出来。

Direct Blending

除了上述的通过参数计算出各个动画权重的方式,还有直接用参数作为权重的方式。


unity 内部接口协议_unity 给模型绑定骨骼_09


这样可以直接而非间接地控制动画的混合,可以看见每个动画都被直接分配到一个参数上,因为直接所以事实上是最灵活的类型,可以用其实现淡入淡出、甚至自己的 2d 混合算法,还可以结合 blend shape 做出复杂的表情动画。

blend shapes

Blend Shape 也是依赖 SkinnedMeshRenderer 组件,打开该组件即可看到各个shape 的权重。


unity 内部接口协议_unity 给模型绑定骨骼_10


基本原理是各个预设好的 shape 的顶点按照权重去混合,成本不低(相比起骨骼动画而言),一般只用于脸部表情等精细部位。

总结

大体上过了一下 Unity 动画基于 state machine 还有基于 Blend Tree 的两种机制,其实两者并非互斥的,Blend Tree 本身也是 state machine 中的一个 state,它只是提供了另一种动画控制与平滑过渡的机制。

参考

https://docs.unity3d.com/Manual/AnimationSection.htmldocs.unity3d.com