UDN
Search public documentation:

AnimationOverviewCH
English Translation
日本語訳
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 主页 >动画 >动画系统概述
UE3 主页 > 动画制作人员 > 动画系统概述
UE3 主页 > 过场动画制作人员 >动画系统概述

动画系统概述


概述


虚幻引擎3动画系统可以给所渲染的物体和实体添加运动效果。骨骼可以产生动画的网格物体称为骨架网格物体。和静态网格物体不同(它仅能通过Matinee进行动画,材质通过世界位置偏移产生动画),骨架网格物体具有一组构成骨架的骨骼。这些骨骼用于驱动物体的运动及在网格物体上物体的放置位置。

动画系统有4部分 - 关键帧动画数据的播放、动画混合、控制骨骼及顶点变形目标混合。

管道


动画系统是虚幻引擎3处理流程的一部分。首先,处理一般的动画(混合动画)。然后应用骨骼控制器(比如Inverse Kinematic(逆向运动学))。接下来应用顶点变形目标。最后,为骨架设置物理。然后物理子系统处理剩余的物理,最后图形子系统渲染所有的物体。

Animation-Pipeline.JPG

工作流程

一般,程序员和动画制作人员一同工作来制作所需要的动画内容。动画制作人员将设置一个骨架并根据一个达成一致的惯例来为骨骼添加标签。程序员将基于处理方法(类、函数、标记等)把所有的这些结合在一起。

带动画的网格物体

在虚幻引擎中,带动画的网格物体称为Skeletal Meshes(骨架网格物体),因为基于骨骼的骨架动画是用于驱动游戏中物体的动画的主要机制。在之前的虚幻引擎2和虚幻引擎1中,也有基于顶点的动画。不再支持关键帧顶点动画。

动画混合


虚幻引擎3使用'混合树'的观念来把多个动画数据源混合到一起。这个方法使您可以清晰地管理多个动画的混合方式,并且随着您游戏的开发不断地前进,使您可以轻松地以可预知的方式添加多个动画。

混合树概述


这是一个简单的动画混合树:

animtreediagram.gif

树是由一些树节点组成。节点主要有两类:

  • Blend Nodes(混合节点) (圆形) - 这些节点有一组子节点,并以某种方式把它们混合到一起。用于混合处理的基类是AnimNodeBlendBase。
  • Data Nodes(数据节点) (方形) - 是树的叶子节点,没有子节点但实际上可以生成骨架变换。

在这个例子中,'Directional Blend'节点将会基于actors的速度和方向来把连接到它们上的定向动画混合到一起。这将会产生一个定向行走动及跑动的动画。然后这些节点插入到一个'Speed-based(基于速度)'的混合中,它将基于Actor的速度把两个子节点混合到一起。最后,有一个‘基于开火的混合’,如果Actor正在开火其武器,那么将混入到开火动画。

基于引擎中定义的几种简单基本混合节点类型来创建专用的混合类型是非常容易的。

请查看[[AnimationNodes] [动画节点]]页面来查看关于虚幻引擎3中的可用动画节点的更多信息。

构建混合树

动画树可以使用AnimTree(动画树)编辑器进行构建,它是虚幻编辑器的一部分。您可以使用内容浏览器创建一个新的AnimTree(动画树),然后双击它,便可以打开AnimTree(动画树)编辑器,并看到一颗新的空的树。

然后,您可以让一个骨架网格物体组件在其默认属性块中使用您的动画树:

defaultproperties
{
  Begin Object Class=SkeletalMeshComponent Name=SkeletalMeshComponent
    SkeletalMesh=SkeletalMesh'BigCritter.CritterMesh'
    AnimSets(0)=AnimSet'BigCritter.CritterAnims'
    AnimTreeTemplate=AnimTree'BigCritter.CritterAnimTree'
  End Object
}

把AnimTree(动画树)分配给AnimTreeTemplate(动画树模板)是非常重要的,而不是分配给Animations(动画)。当动画播放开始时,将复制AnimTreeTemplate(动画树模板)引用的AnimTree(动画树),然后把这个实例分配给Animations(动画),这个实例是游戏播放中真正使用的,因为它包含着实际的状态。

点击这里查找关于动画树编辑器的更多信息。

AnimTree(动画树)节点

AnimTree(动画树)节点是建立一个新的AnimTree(动画树)时默认存在的节点。这是您连接您的动画节点骨骼控制器顶点变形节点的地方。

动画混合节点和动画序列将会产生最终的动画。下一步是应用骨骼控制器。这个工作是以单个步骤完成的,因此骨骼的顺序很重要。让我们设想一下以下的情境: 人物使用IK来移动手臂,使用程序控制器来处理手臂的关节。您将会先使IK完成动作,然后关节完成动作,这样它可以产生最终的姿势。为了解决这个问题,骨架可以在三次渲染中进行排列。

  • ComposePrePassBoneNames - 首先要组成的骨骼及其子项。一般是IK Bone 链。
  • ComposePrePassBoneNames - 最后要组成的骨骼及其子项。一般是roll bones(关节)。

动画播放


AnimSequence(动画序列)

一个AnimSequence(动画序列)是一个单独的动画,它是一个关键帧集合,包含着许多相关的元数据信息,比如notifies(通知)。

AnimSet(动画集)

一个AnimSet(动画集)是一个AnimSequences(动画序列)的集合。它们存在于包中,并且可以像材质、网格物体等以同样的方式内容浏览器中进行查看。

AnimSets_ContentBrowser.jpg

在一个动画集中的所有AnimSequences(动画系列)必须具有同样数量的轨迹,并且这些轨迹必须指向相同的骨骼。当您在动画集编辑器导入一个 FBX 文件时尤其应该小心。

骨骼到轨迹的映射

在AnimSet(动画集)中的轨迹是通过名称和骨架网格物体中的骨骼相关联的。这是因为您或许会想在不同的骨架网格物体上播放同样的动画集,但这些骨架网格物体的骨骼的数量和顺序是不一样的。要想快速地查找存储着一组AnimSetMeshLinkup结构的动画树。这些是特定骨架网格物体上的骨骼和AnimSet(动画集)的轨迹之间的映射表。

AdditiveAnimation(叠加型动画)

默认情况下,AnimSequences(动画序列)存储完整的骨架动画。但是它也可以构建并使用叠加型动画。叠加型动画通过在AnimSet(动画集)编辑器中对两个动画相减来进行构建。然后动画树再使用几个节点把这个叠加型动画添加回去。Additive Animation(叠加型)动画通过去掉冗余数据从而可以作为一种压缩方式。(比如:放松的走步和瞄准的走步,取出这两种走步,仅保存放松走步和瞄准走步的不同作为一个附加部分)。尽管是一个进行操作的小技巧,但它可以在很大程度上降低所使用的动画的数量并降低所使用的内存空间。

尽管动画集编辑器中动画靠它本身便可以达到很好的效果,但是在游戏中它需要被添加到一个基础姿势中,从而看上去更加形象。 您可以通过使用AnimNodeAdditiveBlending节点或者仅通过在一个AnimNodeSlot上根据需求播放它们来添加叠加型动画。

Additive(叠加型)动画、 Target(目标)动画和Base(基础)动画都保持着彼此间的引用。在不同的动画集中移动这些动画并维持这些引用(但不是包)是安全的。当导入一个Target(目标)或Base(基础)姿势的更新版本时,编辑器将会提醒用户来重新构建相关的叠加型动画。

如果您想更新现有数据并创建这些引用,您可以运行FixAdditiveReferences命令开关。

AnimNodeSequence(动画节点序列)

这是AnimNode(动画节点)的子类,它知道怎样播放存储在AnimSets(动画集)中的关键帧数据。它一般构成了您的混合树的叶子节点。

您想要播放的动画序列可以通过在AnimNodeSequence(动画节点序列)中的名称来指定。为了找到那个AnimSequence(动画序列),它将会查找SkeletalMeshComponent中的整个AnimSets(动画集)数组。通过名称引用动画序列而不是通过指针进行引用的优点是:它允许您为完全不同的网格物体/动画使用相同的树。当搜索整个AnimSets数组时,它将从末端开始并向前查找,直到找到具有那个名称的AnimSequence的AnimSet。这允许您在数组中通过添加一个新的具有同样名称动画序列的AnimSet来覆盖特定的序列。

AnimGroups(动画组)

当要同时管理很多不同的动画时,在较高的层次上来组织和管理这些动画变成了急需的功能。为了解决这个问题,动画系统使用了AnimGroups(动画组)的概念。

通过使用AnimGroups,使得同步一系列节点到一起、仅使组中最重要的节点触发通知、及全局地调整所有这些节点的播放速度成为可能。它也可以是这些选项的组合,不是所有的节点都需要同步。

同步
这个过程在使用一个称为AnimNodeSynch的特殊节点前完成。这个操作自从被集成到AnimGroup系统中时便已经存在。所以如果您当前在所有您的动画树中使用的都是它,那么我们鼓励您移除这个 AnimNodeSynch 节点。

动画同步背后的原理是可以把不同长度的动画同步到一起。这是非常有用的,比如,对于运动循环。在走动和跑动间的无缝转换。这个主意是为了使动画相对同步。比如,在整个运动循环中,左脚下降为0%,右脚下降为50%。现在,如果我们保持走步和跑动循环相对地同步到一起,我们便可以根据任务的速度和任何走步循环的无缝变换来改变每个循环的播放速度。

通知
当在相似的动画间进行变换时,也存在一个处理通知的问题。比如,具有运动动画的脚步。当在不同循环间变换并使用基于权重界线的系统来触发通知时,您可能会以根本没有触发任何通知的情况告终(或者有时候,可以一次触发几个通知)。我们实际上希望的是这一组动画中最重要的那一个来负责触发通知。使用AnimGroups可以解决这个问题。

组可以进行播放速度控制
最终,AnimGroups也允许在组的层次上控制动画的播放速度。注意这是除了每个动画节点速率之外的操作。所以动画节点可以有不同的/各种各样的速度,而组速度将在它们独立的播放速率之上来缩放那个组中所有动画节点的速率。

设置
为了创建一个组,请选择AnimTree节点(混合树的根节点)。展开AnimGroups,并添加一个新项。在‘GroupName(组名)’属性中为您的组输入您想使用的名称。RateScale属性是用于缩放这个组的全局播放速度。

然后,选择您想添加到这个组中的AnimNodeSequence节点。展开它的Group部分。您将会看到以下属性:

  • Force Always Slave - Node(节点)将会被同步,但是永远不会被选择为主要节点。
  • Synchronize - 默认为真,节点将会被同步。如果您不想同步这个节点,请不要选中此项。
  • Synch Group Name - 这个节点所属的组的名称。设置它为和您在AnimTree AnimGroups 数组中创建的组名称一样的组。
  • Synch Pos Offset - 如果所创建动画不是和其它动画(左脚、反向的右脚)进行相对地同步,那么通过偏移动画来使它匹配是可能的。Offset (偏移)是一个相对位置,从0.f到1.f。

内部实现
当所有的节点被实时计算后,分组系统在第二遍中它将会强制更新组中所有的节点。所以在混合树中的所有节点都具有最新的权重。然后每个组将会寻找两个主要节点。一个用于同步,另一个用于通知。要使用2个主要节点的原因是不是所有的节点都需要被同步,并且也不是所有的节点都需要触发通知。所以在每个种类中的主要节点都是最相关的节点(在树中具有最高权重的节点,可以活着被同步活着触发通知)。一旦选择了主要节点,那么所有的组节点都是补充资料。需要同步的节点是,需要触发通知的节点也是。

Unrealscript 函数
  • SetAnimGroupForNode(AnimNodeSequence SeqNode, Name GroupName, optional bool bCreateIfNotFound) - 向现有动画组添加一个节点。
    • Seq Node - 要添加的动画序列节点。
    • Group Name - 要添加动画序列的动画组名称。
    • Create If Not Found - 如果没有发现动画组,那么创建动画组。
  • GetGroupSynchMaster(Name GroupName) - 返回为这个组启动同步的主要节点。
    • Group Name - 动画组名称。
  • GetGroupNotifyMaster(Name GroupName) - 返回为这个组启动通知的主要节点。
    • Group Name - 动画组名称。
  • ForceGroupRelativePosition(Name GroupName, float RelativePosition) - 强制组在一个相关的位置。
    • Group Name - 动画组名称。
    • Relative Position - 要设置给这个组的相关位置。
  • GetGroupRelativePosition(Name GroupName) - 获取组的相关位置。
    • Group Name - 动画组名称。
  • SetGroupRateScale(Name GroupName, float NewRateScale) - 调整组的 Rate Scale(速率缩放比例)。
    • Group Name - 动画组名称。
    • New Rate Scale - 要设置给组的速率缩放比例。
  • GetGroupRateScale(Name GroupName) - 获取组的 Rate Scale(速率缩放比例)
    • Group Name - 动画组名称。
  • GetGroupIndex(Name GroupName) - 会返回给定 GroupName 的 AnimGroups 列表中的索引。如果无法找到组,那么将会返回 INDEX_NONE。
    • Group Name - 动画组名称。

根骨骼运动

根运动允许您从动画中提取加速 / 速度和旋转数据装入到虚幻引擎 3 的物理系统中。请参照根运动页面了解更多信息。

骨骼控制器


当动画已经被提取出来并混合到一起后,便可以应用骨骼控制器,比如IK(逆向运动学)。请查看SkeletalControllers(骨架控制器)页面来获得关于这个步骤以及您可以使用的节点类型的更多信息:

物理动画


关于将 PhysX 和动画结合起来的更多信息,请参照物理动画页面。

常见问题


非统一骨骼缩放

  • 我们不支持非统一骨骼缩放,但是对于那些想要进行这些操作的授权用户,可以使用附件,相信会有所帮助。

https://udn.epicgames.com/pub/Three/AnimationOverviewCH/NonUniformBoneScaling.rar

有用的控制台命令


  • show bones - 会显示用于渲染骨架网格物体的骨骼的位置。