Bootstrap

Mecanim Animation System

动画系统简介

Unity 有一个非常丰富而又复杂的动画系统,官方称其为Mecanim。该系统具有以下功能:

  • 支持从外部导入动画剪辑,如:fbx、mb | ma(Autodesk maya 原件)、.max(3ds Max原件)、.blend(Blender 原件

  • 从Unity编辑器创建简单的动画剪辑

  • 提供动画剪辑关键帧到脚本的交互

  • 人形动画重定向,将动画通过Avatar系统从一个模型转移到另一个模型上

  • 预览(编辑器|运行时)动画剪辑以及他们之间的过度与交互

  • 提供可视化工具来管理动画之间的复杂交互

  • 分层管理与遮罩

3ds Max原件在导入时会被转换为FBX格式

需要安装Blender软件才能正常导入.blend

动画系统的工作流程
  1. 由艺术工作者提供剪辑资源

  2. 通过Animator Controller(动画状态机)协调动画之间的衔接、过度、混合

  3. 制作人形角色的Avatar模具或遮罩,包含骨骼映射、肌肉设定

  4. 将Animator和Avatar赋予给不同的模型以实现动画共享

        不建议将这个动画系统应用于图形用户界面,应为它比简单的Tween动画要至少高出30%的开销。

        通常场景中简单游戏对象的动画只需要用到1或2两个环节

        是否需要用到Avatar系统,取决于你的人形动画的通用程度,例如某个BOSS的动画集的通用动画占比不足10%,那么放弃Avatar系统可以帮助你提升30%~50%的CPU计算性能。

Mecanim 动画系统的工作流程
Avatar基础用户手册
简介

        在Unity中Avatar是用来描述骨骼及肌肉组织的接口,它以附加资产的形式寄存在模型或动画资源上。

创建或引用Avatar
从模型创建Avatar功能入口

        你可以在模型导入时,通过Avatar Definition=Create From This Model来为当前的模型新建一个Avatar实例,也可以从其他模型中引用已经创建完毕的Avatar实例。

注意:引用其他模型的Avatar实例,需要保证当前模型的骨骼结构(包括骨骼命名)与被引用的模型一致。

为Avatar资产配置骨骼映射
配置Avatar功能入口
配置Avatar编辑器入口
骨骼映射编辑界面

默认情况下,Unity会自动映射。

自动映射功能入口

在骨骼意外丢失的情况下,可以通过Mapping>Auto map进行自动映射。

当然你可以可以通过Save功能导出一个骨骼模板,提供给其他模型使用。

同时你可以可以通过Load功能载入一个骨骼模板,应用到当前Avatar资产中。

重置模型到T-Pose

 如果资产的骨骼没有进入到T-Pose状态,可能会导致表现上的错误。

你可以通过Enforce T-Pose使它强制进入到T-Pose姿态。

为Avatar配置肌肉参数
肌肉配置面板
浏览调整的姿态

         浏览姿态面板可以让你更好的了解,当前肌肉参数配置下网格最基本的形变是否会发生严重扭曲、挤压、破皮等现象。

模型穿透的例子
调整参数修复穿模

        在这里我将原有的值从40调整到27,修复了模型穿透的现象。

        总之它可以帮助我们约束骨骼的活动姿态,从而使表现达到最佳的效果。

        正常情况下这个姿态产生的问题需不需要修复,取决于你的动画剪辑中是否涉及到该姿态的表现,如果没有,你完全可以忽略它。

模型Avatar与动画剪辑Avatar的关系

        在使用Avatar进行动画共享的正常情况下,动画剪辑可能会来自不同的模型,这意味动画剪辑的Avatar配置不一定能完全适用当前的模型形变。在这种情况下,就需要两个Avatar,动画剪辑Avatar提供标准的姿态配置,而模型的Avatar提供一个不破坏网格形变的姿态配置。

        假设你的动画剪辑Avatar完全可以适应模型的形变,那么他们完全可以使用一个Avatar实例。

        在有两个Avatar工作过程中,模型的Avatar会接收动画剪辑Avatar吐出的姿态数据,并根据自身的肌肉设定再次对姿态进行调整,最终应用到网格形变上。

Animator基础用户手册

        Animator Controller是Mecanim Animation System的核心功能,它涉及到非常多的内容,在这篇文章我只做了最基础的介绍。

简介

        Animator Controller又叫做动画状态机,它的工作原理与状态机类似,它利用Animation Clip(动画剪辑)作为单位节点。在Animator中每个节点都属于一个单独的状态,它允许你根据条件设置动画如何从状态A过度到状态B,以表示角色的形态。

        与普通状态机不同的是,它支持动画状态的混合和叠加。

        混合更像是程序世界的Switch Ease语句,它可以根据某个属性在一组动画中随意过度。

        而叠加是通过权重去控制不同分层的动画状态,最终作用于同一模型上的结果。

创建Animator Controller
创建Animator Controller功能入口
Animator Controller 编辑窗口 
Animator Controller 窗口布局
 工作流程
  1. 在状态面板中编辑动画状态之间的转换
  2. 在参数面板编辑适用于跳转的参数变量
  3. 将参数变量应用到跳转上
  4. 编辑动画跳转过程中的过度方式
  5. 通过脚本控制Animator Controller实例暴露的参数,以达到改变动画行为的目的
新增一个动画状态到编辑区

最简单的办法是拖拽一个Animation Clip资产,到编辑区域视口

当然你也可以效仿下面方式,通过菜单创建状态节点

创建一个空的动画状态
为新节点设置动画剪辑

  1. 选中剪辑
  2. 打开Motion属性的选择器
  3. 选择一个合适的剪辑
创建一个Transition
步骤1和2
  1. 在原节点上右键打开菜单,并选择Make Transition
  2. 拖拽引线到目标节点
使用变量控制Transition 
添加变量
  1. 在参数面板,打开变量菜单
  2. 选择变量类型
  3. 为变量命名
为变换应用参数

  1. 添加控制条件
  2. 选择控制变量
  3. 选择比较值

        到这里为止,一个简单的循环就完成了。

        当然在实际应用过程中还会涉及到状态属性、跳转属性、BlendTree、叠加层、子状态机、覆盖控制器等很多的编辑知识,单独写一个文章介绍。 

为游戏对象配置相关资产
为GameObject配置相关资产
  1. 要挂载 Animator 组件
  2. 配置 Animator Controller(动画控制器)
  3. 配置模型的 Avatar实例
扩展
动画剪辑的参数设置
Animator是如何适配模型的骨骼结构的?

        当Animator开始工作的时候,它会从跟节点开始遍历寻找与骨骼匹配的跟节点,在确定骨骼根节点之后,它会将网格模型的骨骼结构和骨骼节点名称和Avatar配置的骨架做对比,直到找到一个完全一样的骨架。

        当子节点下有两个相同结构的骨骼模型时,Unity总是会选择排序最靠前的模型作为骨骼动画的输出目标。

        这意味着你在子节点上挂载两个模型都适用与该Avatar的时候,即使排序靠前的模型是隐藏的,那么Unity依然会选择它作为输出目标,另外一个即便是显示的也不会动哟。


Unity 骨骼树形结构

Root (根节点)
|-- Hips (髋部)
    |-- LeftUpLeg (左大腿)
        |-- LeftLeg (左小腿)
            |-- LeftFoot (左脚)
                |-- LeftToes (左脚趾)
    |-- RightUpLeg (右大腿)
        |-- RightLeg (右小腿)
            |-- RightFoot (右脚)
                |-- RightToes (右脚趾)
|-- Spine (脊柱)
    |-- Spine1 (脊柱1)
    |-- Spine2 (脊柱2)
|-- Chest (胸部)
|-- Neck (颈部)
|-- Head (头部)
    |-- HeadTop (头顶)
|-- LeftShoulder (左肩)
    |-- LeftArm (左臂)
        |-- LeftForearm (左前臂)
            |-- LeftHand (左手)
                |-- LeftHandThumb (左手拇指)
                    |-- LeftHandThumb1 (左手拇指1)
                    |-- LeftHandThumb2 (左手拇指2)
                |-- LeftHandIndex (左手食指)
                    |-- LeftHandIndex1 (左手食指1)
                    |-- LeftHandIndex2 (左手食指2)
                |-- LeftHandMiddle (左手中指)
                    |-- LeftHandMiddle1 (左手中指1)
                    |-- LeftHandMiddle2 (左手中指2)
                |-- LeftHandRing (左手无名指)
                    |-- LeftHandRing1 (左手无名指1)
                    |-- LeftHandRing2 (左手无名指2)
                |-- LeftHandPinky (左手小指)
                    |-- LeftHandPinky1 (左手小指1)
                    |-- LeftHandPinky2 (左手小指2)
|-- RightShoulder (右肩)
    |-- RightArm (右臂)
        |-- RightForearm (右前臂)
            |-- RightHand (右手)
                |-- RightHandThumb (右手拇指)
                    |-- RightHandThumb1 (右手拇指1)
                    |-- RightHandThumb2 (右手拇指2)
                |-- RightHandIndex (右手食指)
                    |-- RightHandIndex1 (右手食指1)
                    |-- RightHandIndex2 (右手食指2)
                |-- RightHandMiddle (右手中指)
                    |-- RightHandMiddle1 (右手中指1)
                    |-- RightHandMiddle2 (右手中指2)
                |-- RightHandRing (右手无名指)
                    |-- RightHandRing1 (右手无名指1)
                    |-- RightHandRing2 (右手无名指2)
                |-- RightHandPinky (右手小指)
                    |-- RightHandPinky1 (右手小指1)
                    |-- RightHandPinky2 (右手小指2)

;