Unity动画系统详解(一)

360影视 2025-01-19 00:25 2

摘要:Controller:这是Animator Controller的引用,它定义了要使用哪些动画剪辑,并控制这些剪辑何时以及如何混合和过渡。Animator Controller相当于动画剪辑的“剧本”,指导着动画的播放和切换。Avatar:对于人形角色,Ava

Animator组件参数介绍

Unity中的Animator组件是控制动画播放的核心,它允许你将动画分配给场景中的游戏对象。以下是Animator组件的一些关键参数及其功能:

Controller:这是Animator Controller的引用,它定义了要使用哪些动画剪辑,并控制这些剪辑何时以及如何混合和过渡。Animator Controller相当于动画剪辑的“剧本”,指导着动画的播放和切换。

Avatar:对于人形角色,Avatar是必需的,它定义了角色的骨骼结构和肌肉系统。Animator通过Avatar来驱动人形角色的动画。如果游戏对象不需要人形动画,这个字段可以为空。

Apply Root Motion:这个选项决定了动画中的根运动(位置和旋转变化)是直接应用于角色的根节点,还是需要通过脚本来控制。如果启用,动画中的移动和旋转会直接影响角色的位置和方向。

Update Mode:这个选项控制Animator何时更新动画状态。

Normal:Animator与Update调用同步更新,速度与当前时间标度匹配。

Animate Physics:Animator与FixedUpdate调用同步更新,与物理系统步调一致,适用于需要物理交互的动画。

Unscaled Time:Animator与Update调用同步更新,但忽略当前时间标度,以100%的速度进行动画化,适合GUI系统或需要不受时间缩放影响的动画。

Culling Mode:这个选项决定了当游戏对象不在摄像机视野内时,动画的剔除行为。

Always Animate:即使在屏幕外也始终进行动画化。

Cull Update Transforms:当未显示渲染器时,禁用变换组件的重定向、IK和写入。

Cull Completely:当未显示渲染器时,完全禁用动画。

动画曲线信息:Animator组件底部的信息框提供了Animator Controller使用的所有剪辑中所用数据的明细,包括动画剪辑的数量、位置/旋转/缩放的曲线总数、肌肉动画曲线数量等。这些信息有助于了解动画的复杂性和性能消耗。

通过这些参数,你可以精细控制动画的播放行为,包括动画的混合、过渡、速度以及与游戏世界的交互。Animator组件是Unity动画系统中不可或缺的一部分,它为游戏对象提供了丰富的动画功能。

新旧动画系统的区别

Unity的动画系统经历了几次重大更新,主要分为旧版动画系统和新版Mecanim动画系统。以下是两者的主要区别:

系统架构:

旧版动画系统:使用Animation组件和Animation Clip资源。Animation组件负责播放动画片段,而Animation Clip则是保存动画数据的资源文件。旧版系统相对简单,但功能有限,不支持复杂的动画逻辑和状态机。

Mecanim动画系统:引入了Animator ControllerAnimator组件。Animator Controller用于定义动画状态和转换规则,Animator组件则负责根据这些规则播放动画。Mecanim系统支持复杂的状态机和过渡,以及动画混合和重定向。

动画剪辑和状态机:

旧版动画系统:动画剪辑是基本的动画单元,没有状态机的概念,动画之间的切换需要通过脚本来控制。

Mecanim动画系统:除了动画剪辑,还有Animator Controller中的状态机,它允许开发者定义多个动画状态(动画片段)和这些状态之间的转换条件和过渡效果。

动画混合和重定向:

旧版动画系统:支持有限的动画混合,通常通过Layer来实现,但功能较为基础。

Mecanim动画系统:提供了更高级的动画混合功能,如Blend Trees,允许开发者创建平滑的动画过渡。此外,Mecanim还支持动画重定向,即将一个角色的动画应用到另一个角色上,这对于角色共享动画非常有帮助。

根运动(Root Motion):

旧版动画系统:不支持根运动的概念。

Mecanim动画系统:支持根运动,允许动画中的移动和旋转直接应用于角色的根骨骼,这样可以简化角色控制代码,并提高动画的自然度。

动画事件:

旧版动画系统:支持在动画中设置事件,这些事件可以在特定时间点触发。

Mecanim动画系统:也支持动画事件,并且可以在状态机中更灵活地使用这些事件。

性能和优化:

旧版动画系统:在处理复杂动画时可能性能较低。

Mecanim动画系统:提供了更多的优化选项,如动画层混合、骨骼混合和加法混合,以及对动画更新频率的控制。

易用性和灵活性:

旧版动画系统:相对简单,易于理解和使用,但灵活性有限。

Mecanim动画系统:提供了更多的自定义选项和灵活性,但学习曲线相对较陡。

总的来说,Mecanim动画系统是Unity推荐使用的系统,它提供了更强大的功能和更好的性能,适合开发复杂的游戏动画。而旧版动画系统虽然仍然可用,但主要用于向后兼容旧项目,不建议用于新项目。

Controller及动画状态机介绍

动画状态机是Animator Controller内部的逻辑核心,它是一个可视化的流程图,用于定义和管理不同的动画状态以及这些状态之间的过渡。

主要组成部分:

状态(States):状态机中的每个状态都对应一个或多个动画片段。状态代表了游戏对象在某一时刻的动画表现,如站立、行走、跑步等。

过渡(Transitions):过渡定义了从一个状态到另一个状态的变化条件。这些条件可以是基于时间的(例如,一个动画片段播放完毕后自动过渡到另一个状态),也可以是基于参数的(例如,当玩家速度超过某个阈值时从行走状态过渡到跑步状态)。

入口和出口:每个状态都有入口(Entry)和出口(Exit)的概念。在状态的入口,可以定义一些初始化的操作,如重置某些参数;在状态的出口,可以定义一些清理操作。

层(Layers):状态机支持层的概念,允许开发者创建复杂的动画逻辑,如上半身和下半身的动画分离。每一层都可以有自己的状态机,这样可以独立控制不同部分的动画。

子状态机(Sub-state Machines):子状态机用于管理特定层的复杂动画逻辑。它们可以包含自己的状态和过渡,从而实现更细粒度的动画控制。

任何状态(Any State):这是一种特殊的过渡,允许从任何状态无条件地过渡到另一个状态。

通过Animator Controller和动画状态机,开发者可以实现复杂的动画逻辑,如角色的行走、跑步、跳跃、受伤等动作的平滑过渡,以及根据游戏逻辑动态调整动画表现。这些工具为游戏角色赋予了丰富的动画表现力,提升了游戏的沉浸感和玩家体验。

状态机相关回调 代码

OnAnimatorMove:

这个回调允许你在动画移动根骨骼时使用动画数据。

通常用于将动画数据应用到游戏对象的Transform上,例如,当动画包含角色移动时,你可以使用这个回调来同步角色的位置和旋转。

void Update { Animator animator = GetComponent; if (animator) { // 获取Animator的根运动 Vector3 animationDelta = animator.deltaPosition; // 将根运动应用到游戏对象的位置 transform.position += animationDelta; // 如果动画包含旋转,则应用旋转 if (animator.applyRootMotion) { transform.rotation = animator.rootRotation; } }}

Animation Events:

动画事件可以在动画片段的特定时间点触发,用于同步动画与其他游戏逻辑,如播放声音或触发特效。


public class AnimationEventExample : MonoBehaviour { void PlayFootstepSound(float左脚, float右脚) { // 根据脚的参数决定播放哪个脚步声 if (左脚) { // 播放左脚脚步声 } else if (右脚) { // 播放右脚脚步声 } }}

在动画片段中,你可以在特定的帧上添加事件,并在事件的数据字段中填写调用的函数名(如"PlayFootstepSound true false")。

OnStateEnter和OnStateExit:

这些回调在进入或退出特定动画状态时触发。

可以用来初始化状态进入时需要的变量,或者清理状态退出时的资源。



void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo) { // 状态进入时的代码} void OnStateExit(Animator animator, AnimatorStateInfo stateInfo) { // 状态退出时的代码}

OnStateMachineEnter和OnStateMachineExit:

这些回调在进入或退出整个状态机时触发。

可以用来设置状态机级别的初始化和清理。


void OnStateMachineEnter(Animator animator, int stateMachinePathHash) { // 状态机进入时的代码} void OnStateMachineExit(Animator animator, int stateMachinePathHash) { // 状态机退出时的代码}

请注意,上述代码示例中的函数需要挂载到带有Animator组件的游戏对象上,并且需要在Animator Controller中正确配置回调状态行为。

动画混合树

混合树的类型:

1D混合树:根据单个参数(如速度)在动画片段之间进行混合。适合用于需要在一个维度上变化的动画,例如从站立到行走再到奔跑的平滑过渡

2D混合树:根据两个参数在动画片段之间进行混合。适合用于需要在两个维度上变化的动画,例如角色在奔跑时同时需要左右转向的情况

直接混合树(Direct Blend Tree):允许直接将Animator参数映射到Blend Tree子项的权重,适用于需要精确控制动画混合的情况,如面部表情的混合。

创建和使用混合树:

在Animator Controller中创建新的混合树状态,可以通过在Animator窗口的空白处右键,选择“Create State > From New Blend Tree”来完成。

双击Blend Tree进入混合树的编辑界面,在这里可以添加多个动画片段,并选择一个Float类型的参数作为控制变量。

动画混合树的过渡:

混合树中的过渡是实时进行的,根据参数值的变化,动画片段会以不同的比例混合在一起,创造出平滑的过渡效果。

例如,当参数值为0时,可能完全播放站立动画;当参数值增加时,站立动画和行走动画会以一定比例混合,直到完全过渡到行走动画。

代码控制:

可以通过脚本来实时控制Animator参数的值,从而控制混合树中动画的播放和混合。例如,根据角色的移动速度来调整混合树参数的值。

混合树的优化:

为了使混合树工作得更好,需要确保参与混合的动画片段在标准化时间内的相同点进行对齐,例如,左脚接触地面的瞬间。


1D混合树

在Unity的动画系统中,1D混合树(1D Blend Tree)是一种用于根据单个参数值在两个或多个动画片段之间进行混合的工具。这种混合树特别适用于需要在单一维度上变化的动画,例如角色的移动速度从慢到快(如行走到奔跑)。

以下是1D混合树的一些关键特点和使用方法:

参数控制:

1D混合树使用一个参数(通常是Float类型)来控制不同动画片段之间的混合。这个参数可以是角色的速度、时间或其他任何可以量化的属性。

混合节点:

在1D混合树中,每个动画片段都对应一个节点,这些节点根据参数值在线性或非线性方式上排列。

混合曲线:

开发者可以为每个节点设置混合曲线,这条曲线定义了该节点在参数值变化时的活跃程度。混合曲线可以是线性的,也可以是更复杂的曲线形状,以实现更平滑的过渡。

自动阈值:

Unity提供了自动计算阈值的功能,允许系统根据参数值的范围自动确定每个节点的混合权重。这可以简化设置过程,但有时手动调整阈值可以提供更好的控制。

平滑过渡:

1D混合树可以创建非常平滑的过渡效果,因为动画片段是根据参数值的连续变化而混合的。

使用场景:

适用于需要在单一维度上平滑过渡的动画,如角色的行走、跑步,或者任何需要根据单一变量变化的动画。

2D混合树

在Unity中,2D混合树(Blend Tree)可以有几种不同的类型,每种类型适用于不同的动画混合场景。以下是2D混合树的主要类型及其特点:

2D Simple Directional:

最适用于运动表示不同方向的情况,例如“向前走”、“向后退”、“向左走”和“向右走”或者“向上瞄准”、“向下瞄准”、“向左瞄准”和“向右瞄准”。

可以包括位置 (0, 0) 处的单个运动,例如“空闲”或“瞄准”。

在 Simple Directional 类型中,同一方向上不应该有多个运动,例如不应该同时有“向前走”和“向前跑”。

如果混合位置是 (0, 0),并且有一个运动在位置 (0, 0),则该运动会有全额权重。如果没有运动在位置 (0, 0),则所有运动将平均分配权重,无论它们的运动位置如何。

2D Freeform Directional:

适用于运动表示不同方向的情况,但与 Simple Directional 类型不同,可以在同一方向上有多个运动,例如“向前走”和“向前跑”。

在 Freeform Directional 类型中,运动集应始终包括位置 (0, 0) 处的单个运动,例如“空闲”。

每个运动场都有一个邻居列表,包含了所谓的每个运动场的“邻域”。Unity有一个复杂的算法来计算权重和邻域。

2D Freeform Cartesian:

最适用于运动不表示不同方向的情况。

凭借 Freeform Cartesian,X 参数和 Y 参数可以表示不同概念,例如角速度和线速度。

一个示例是诸如“向前走不转弯”、“向前跑不转弯”、“向前走右转”、“向前跑右转”之类的运动。

Freeform Cartesian 类型也有邻居列表,但Unity在这个类型中不关心角度,只关心位置。这与 Unreal Engine 4 中的 2D Blend Space 类似,并且是我们Unity项目中最常用的混合类型。

Direct:

此类型的混合树让用户直接控制每个节点的权重。

适用于面部形状或随机空闲混合。

设置混合类型后,首先需要选择两个动画参数来控制此混合树。

每种2D混合树类型都有其特定的用例和优势,开发者可以根据具体的动画需求选择合适的混合树类型。在性能方面,Simple Directional 通常是最经济的,而 Freeform Directional 可能是最昂贵的。开发者可以根据需要选择最合适的类型来实现所需的动画效果。

来源:平和

相关推荐