游天堂X游聚社区

标题: Unity动画系统设计 [打印本页]

作者: 天狗    时间: 2021-2-24 20:02
标题: Unity动画系统设计
内容大纲
动画系统简介
动画曲线(AnimationCurve)[attach]1945853[/attach]
动画资产资产的导入
动画片段(AnimationClip)[attach]1945854[/attach]
动画控制器[attach]1945855[/attach]
Avatar

重定向方案人形动画系统(Humanoid)
重定向数据
根节点运动(Root Motion)
动画片段(Clip)设置相关-存在RootMotion时[attach]1945856[/attach]
RootTransform与BodyTransform
根节点运动(Root Motion)逻辑控制方案
Target Match
IK
Mecanim动画计算管线Mecanim设计要理解Mecanim动画系统,必须先理解Mecanim的设计框架:
Mecanim系统是围绕Animator组件设计的,Animator的主要功能是将动画数据输出到具体的骨骼节点(或是其他组件)上,运行时的整个数据流是由树状的PlayableGraph来执行的(改版后),而具体的动画逻辑信息则由相关的AnimatorCo**oller或者代码中直接创建的Playable节点树提供;
具体实现上,Mecanim设计了一套骨骼数据和动画数据分离的框架,AnimationClip上的骨骼数据都被分离储存到了GenericBinding数据集合中,而无任何绑定信息的动画数据则被分离到数据结构ClipMuscleConstant中;
Animator在每次PlayableGraph改变后,都会根据所有动画片数据生成AnimationSet数据,然后绑定到所有的骨骼节点,此时需要Avatar辅助,其中ClipBindings记录每个动画片的独立输出到统一输出的映射,而动画管线只专注于独立的动画数据的计算,在输出阶段输出到各自独立输出部分,再映射到Animator的输入,由Animator节点统一输出到骨骼节点;
[attach]1945857[/attach]
Mecanim数据绑定流程Mecanim的运行时从动画曲线数据出发寻找实际输出组件属性地址的绑定流程可以分为三个阶段,主要是Generic动画类型的流程,Humanoid动画有固定的绑定流程,在绑定数据生成方面没有额外的运行时开销:
[attach]1945858[/attach]
计算流程Mecanim中,Generic动画流程与Humanoid流程在同一管线中完成,因为Mecanim允许一个Humanoid动画中包含Muscle曲线和Generic曲线,所以实际上可以理解成Mecanim动画流程一定有Generic动画流程,而Humanoid动画流程是可选的;
实际流程上Mecanim的两种动画形式产生了一定程度上的分离,Mecanim在一个动画逻辑帧中有两个阶段:FK阶段和IK阶段,其中FK阶段主要完成动画数据采样计算,是二者共有的,而IK阶段则是纯粹的Humanoid动画特有的计算流程;

Generic计算流程
Mecanim框架下,动画数据与骨骼对象没有实际的绑定关系,整个数据流程可以大致划分为两个部分:绑定流程和计算流程,Generic和Humanoid的流程是在一个动画管线流程中完成的,但是涉及的数据结构和算法完全不同,必须分开来理解;
绑定流程主要负责生成动画曲线的输出组件绑定数据,以及在运行时使用绑定数据寻找真正输出的组件和其属性的指针;Generic主要的复杂流程集中在绑定过程中,后续详细讲解;
计算流程就是计算每帧动画采样数据以及将数据输出到对应组件(一般是骨骼)的过程,如果是Humanoid动画,则还需要包含动画重定向和骨骼IK计算的过程;Generic计算流程因为数据直接,计算流程相对简单,就是在PlayableGraph中的叶节点AnimationClipPlayable中中进行曲线数据采样,其后以Animator将数据输出到对应组件;

Humanoid计算流程由于Humanoid动画有一套Human Skeleton Avatar 的骨骼范式,所以Humanoid动画数据流程中的绑定流程相对简单很多,开销也更小,但同时因为多了重定向和IK功能,Humanoid的数据计算流程变得更加复杂,稍后会做详细讲解;
Humanoid动画因为有由固定的必选骨骼和可选骨骼组成的骨骼范式,所以动画曲线和其输出集合组成都是固定的。其使用特殊的数据规范和动画曲线,直接输出到Animator组件,不需要生成对应的GenericBinding,也不参与其后Generic动画的绑定流程;
Humanoid动画片的核心绑定数据结构是一个IndexArray,用于指示动画片采样数据ClipOutput到RootMotion和HumanPose的映射关系;除了在创建MuscleClip的流程里生成IndexArray,和Animator根据Avatar寻找Transform对象,没有其他绑定流程;
PlayableGraph中的采样计算流程只完成将数据输出到HumanPose的流程,其后还需要经过重定向流程将数据输出到AvatarWorkSpace,再经过IK流程输出到SkeletonPose,最后再输出到骨骼节点中;

勾选层级优化的计算流程
由于Unity的Transform的层级设计,所有与Transform打交道的功能的开销都会随着Transform层级的加深而提高,而用于动画的骨骼往往都是多层结构。所以Mecanim支持了一种将骨骼层级扁平化的优化功能,允许FBX等模型文件导入时生成扁平化的骨骼结构,同时Animator也可以把动画数据正常输出到扁平化的骨骼上;
这个功能有很多设计弊病,先按下不表。
如果骨骼结构有扁平优化,则Mecanim的数据流程会发生一些变化。此时因为创建流程不能读取到模型的Transform数据,只能依赖存放在Avatar中的层级数据,即便是Generic动画也必须要将对应的Avatar数据对象提供给Animator;
存在骨骼层级优化的流程与正常流程最大的区别,在于Animator的绑定流程中需要根据Avatar数据寻找到真正的Transform对象并且存储在ExposedTransform中,同时在输出流程中需要增加一步计算将扁平化的骨骼的局部变换矩阵转换到全局变换矩阵输出到Transform上;

FK 阶段Mecanim的FK阶段主要工作是完成Generic动画的大部分流程,主要是:

IK 阶段Mecanim的IK阶段相对复杂,主要是完成动画片采样数据输出到Animator的集中输出结构和Humanoid的重定向以及IK流程,比较关键的流程:






尾巴原本Unity不开放Pose调整的代码,动画系统是一个几乎无法控制的黑盒。即使加上Playable的重构,也只是允许自定义播放动画的逻辑容器,大部分项目也只是劣化Animator Co**oller的流程,并没有解决动画表现扩展方式不足的问题。这个情况在Animation Job和Animation Rigging出现之后有了改善的希望,也有一些项目开始摸索在Unity里实现AnimGraph的可能性。本来傻瓜化的动画系统也是Unity的一大优势,只是文档和标准化的贡献太少,期待以后官方能玩出更多花样。


作者: 王寶强    时间: 2021-2-24 20:28
期待以后官方能玩出更多花样。





欢迎光临 游天堂X游聚社区 (https://bbs.gotvg.com/) Powered by Discuz! X3.1