Animation
# Animation (动画系统 旧版)
# 处理旧版本动画
要导入旧版动画,必须现在 Import Setting 窗口的 Rig选卡中将 Animation Type
设置为 Legacy;
# 属性
Animation: 启用
Play Automaticallyy
默认播放的动画Animations: 提供脚本访问的动画列表
Size: 动画数量
Element.....动画
Play Automatically: 游戏开始时自动播放默认动画
Animation Physics: 启用此选项可使动画与物理系统交互
Culling Type: 确定何时不播放动画
Always Animate: 始终进行动画化。
Based On Renderers: 基于默认动画姿势进行剔除。
Based on Clip Bounds: 基于剪辑边界(在导入期间计算)进行剔除。当剪辑边界不在视野范围内时,不播放动画。
Based on User Bounds: 基于用户定义的边界进行剔除。当用户定义的边界不在视野范围内时,不播放动画。
# 动画片段属性
Length: 长度(帧)
Wrap Mode: 动画模式
Defeault: 默认
Once:播放一次
Loop: 循环播放
Clamp Forever: 动画播放到结尾时候,动画总处于最后一帧的采样状态
Ping Pong: 在开始和结束之间来回播放。
# 详解
动画系统支持动画混合 (blending
)、混组 (mixing
)、附加动画 (additive animations
)、行走周期时间同步
、动画层
、动画播放所有方面(时间
、速度
、混合权重
)的控制、每个顶点有 1 个、2 个或 4 个骨骼的网格蒙皮以及支持物理性布娃娃和程序化动画。为了获得最佳结果,建议您阅读创建优化的角色模型页面,了解在 Unity 中创建具有最佳性能的骨架角色的最佳做法和技巧。
# 动画混合
动画混合 (blending
) 是确保角色具有流畅动画的基本功能。动画师们创建单独的动画,例如,行走循环、奔跑循环、空闲动画或射击动画。在游戏过程中的任何时间点,您都需要能够从空闲动画转换到行走循环或反之。当然,您希望过渡平滑并避免突然的运动颠簸。
# 动画层
“层”是一个非常有用的概念,用于对动画进行分组并确定加权优先级。
Unity 的动画系统可在任意数量的动画剪辑之间进行混合。您可以手动分配混合权重,也可直接使用 animation.CrossFade()
自动分配权重。
# 混合权重总是经过归一化后再应用
假设有一个行走循环和一个奔跑循环,两者的权重都是 1 (100%)。当 Unity 生成最终动画时,它将对权重进行归一化,这意味着行走循环将为动画贡献 50%,而奔跑周期也将贡献 50%。
但是,在播放两段动画时,通常希望优先让其中一段动画获得最大权重。当然,可通过手动方式确保权重总和达到 100%,但这种情况下使用层会更容易。
默认情况下,animation.Play()
和 animation.CrossFade()
将停止或淡出位于同一层的动画。在大多数情况下,这正是我们需要的效果。在我们的射击、空闲、奔跑示例中,播放空闲动画和奔跑动画不会影响射击动画,反之亦然(如果需要,可使用 animation.CrossFade
的可选参数更改此行为)。
# 动画混组
通过动画混组 (mixing
),可将一些动画仅应用于身体的某个部位,从而减少需要为游戏创建的动画数量。这意味着此类动画可通过各种组合形式与其他动画一起使用。
通过在给定的 AnimationState
上调用 AddMixingTransform()
,可将动画混组变换添加到动画。
使用 AddMixingTransform
api添加混组
# 附加动画
通过附加动画和动画混组,可将一些动画仅应用于身体的某个部位,从而减少需要为游戏创建的动画数量。
假设您希望创建一个在行走和奔跑时向侧面倾斜的角色。这导致了四种组合:walk-lean-left(向左倾斜行走)、walk-lean-right(向右倾斜行走)、run-lean-left(向左倾斜奔跑)和 run-lean-right(向右倾斜奔跑),每个组合都需要一段动画。即使在这种简单的情况下,为每个组合创建单独的动画也会导致很多额外的工作,但是每增加一个动作,组合的数量就会大大增加。幸好,附加动画和动画混组避免了为简单动作组合生成单独动画的必要。
# 动画播放和采样
动画剪辑(AnimationClips)通常是固定帧率创作的。例如可在3ds Max或Maya中创建帧率为60帧/秒(fps)的动画,在 Unity导入动画时,导入将读取此帧率,因此动画的数据也以60fps的帧率采样
但是,游戏通常可以变帧运行,一些计算机上的帧率可能高于其他计算机上的帧率,而根据摄像机在任何给定时刻观看的视图复杂性,每一秒的帧率也可能不同。基本上,这意味着我们不能对游戏运行的确定帧率作出任何假设,也就是说,即使动画以60fps创作的,也可能以不同的帧率播放动画。
因此,Unity必须可改变帧率对动画进行采样,并且不能保证最初设计的帧率。 3D计算机图形动画不是由离散帧组成的,而是由连续曲线组成的,在任何时间点都可以对这些曲线进行采样,而不是局限于与原始动画中的帧相对应时间点,事实上,如果游戏运行的帧率高于创作动画的设计帧率,name动画在实际游戏中看起来比在动画软件中看起来更流畅,更稳定
大多数实际情况下,可以忽略unity以可变帧采样动画这件事,但是,如果游戏玩法逻辑依赖于动画的边换组件或者属性到非常具体的配置,那么需要知道重新采样过程在后台进行,例如,有一段动画30帧内将对象从0度旋转到180度,要从代码中知道何时到达中间位置,此情况下不应在代码中使用条件语句(通过条件语句检查当前旋转是否为90度)来实现此目的,因为unity根据游戏的可变帧对动画进行采样,所以可以在旋转刚好低于90度对其进行采样,而在下次到达90度后再进行采样,如果需要在到达动画的特定点时收到通知,应改用 AnimationEvent
另外注意,由于可变帧率采样的原因,使用WrapMode.Once模式播放的动画可能无法在最后一帧的确定时间进行采样。在游戏的一帧中,正好可在动画结束之前进行动画采样,而在下一帧中,时间可能会超过动画的长度,因此会禁用这一帧动画,不对其进行采样。如果必须要对动画的最后一帧采样,应使用 WrapMode.ClampForeve模式,这种模式将无限期对最后一帧进行采样,知道主动停止动画位置