Write Defaults
文章原址:https://notes.sleightly.dev/write-defaults/
Write Defaults
Write Defaults
是动画状态(Animator States)的一个可选项,这对许多虚拟形象创作者来说都是一个令人头疼的问题,因为它们的行为表现比较反直觉。其预期行为如下:
Write Defaults
字段决定动画中所做的更改是否是持久性的。
如果启用了 Write Defaults
字段,则动画字段将模型在离开上一个动画状态时恢复后,在当前动画状态绘制前写回上个动画状态中动画属性的默认状态,不保留上个状态的更改(见示例)。
如果禁用了 Write Defaults
字段,则将不会写回默认状态,保留上个状态的更改(见示例)。
默认情况下,Unity 会在新创建的状态上启用 Write Defaults
,但 VRChat 提供的示例动画控制器是关闭(Animator Controller)没有启用 Write Defaults
了 的。
默认新创建的动画状态为开启 Write Defaults
。
示例:
如果您有一个在层级( Hierarchy )中被禁用(即默认情况下关闭)的帽子(hat),并且您有一个看起来像这样的层级:
在 Write Defaults On
的情况下:
- 当进入 Hat On 的状态时,帽子会切换为开启状态
- 当回到 Hat Off (Empty State)的状态时,帽子会切换为关闭状态(因为这是默认状态)
在 Write Defaults Off
的情况下:
- 当进入 Hat On 的状态时,帽子会切换为开启状态
- 当进入 Hat Off (Empty State)的状态时,帽子将保持开启状态(因为您没有特
别意将其切换回关闭状态或写回默认值)
操作规则
在使用 Write Defaults Off
时,请遵循以下几条规则。我将在下方解释原因(仅为完整性起见):
- 请勿在单个控制器中混合使用
Write Defaults
。混合了使用的Write Defaults
将表现得像Write Defaults Off
。- 此条
的有例外状情况为那些:具有单个状态的层。这些层可以(并应该在或包含 Direct Blend Trees 的情况下单个状态)的层可以被设置为Write Defaults On
。 - 由于
它们上面的层永远不会离开自己的当前状态,因此所以您可以这样做是可以的,我们从不依赖Write Defaults On
行为。
- 此条
- 请勿在包含 Direct Blend Trees 的状态上上使用
Write Defaults Off
- 如果您正在使用
Write Defaults Off
,则您的所有状态都应包含一个动画片段 (AnimationClipClip) 或一个 Blend Tree。这个Animation Clip动画片段可以是空的,但通常建议使用某种绘制了持续两帧不存在的 GameObject ,且持续至少两帧的Animation Clip(有时动画片段(偶尔被称其为buffer clip)。 - 请注意,用
Write Defaults Off
绘制变换动画会覆盖其他正在播放的Animator Controllers动画控制器中的所有变换动画。对于 VRChat则的具体来说例子是:如果您正在绘制 FX 层中的任何变换,它将覆盖 Gesture 层中的所有变换,除非您应用一个仅启用变换动画并禁用所有其他变换的虚拟人形象遮罩(Avatar Masks),并将此遮罩应用到您的 FX 层动画层。
有关遮罩的更多信息,请参阅“Avatar Masks”页面。
请注意:如果您因 Gesture 和 FX 层中的 Write Defaults Off
变换动画而必须使用遮罩,则不能在除第一个材质插槽之外的任何插槽上使用 matswaps,材质切换动画,因为无论遮罩是否启用,被遮罩的变换(无论是启用还是禁用)都不能在除第一个材质插槽之外的其他材质插槽上具有 matswaps 材质切换动画。
VRLabs 的 Avatar 3.0 Manager 是用于检查您是否违背了以上规则的实用工具(检测至少前两条规则) 。在该工具的 Write Defaults
选项卡中,它会告诉您是否混合使用了 Write Defaults
,并会在您按下相应按钮时为您自动设置。请注意,它不会为在设置过程中特意排除 Direct Blend Trees 进行例外规避,Trees,因此包含它们的动画状态必须在其名称中包含(WD On)
字段,以使该工具将其标记为 Write Defaults On
。
解释
不要在单个控制器中混合使用 Write Defaults
处于单个 Write Defaults Off
状态时,这将导致所有其他 Write Defaults On
状态不写入回其默认值,因此并表现为 Write Defaults Off
方式状态。
不要在 Direct Blend Trees 中使用 Write Defaults Off
Write Defaults Off
的 Direct Blend Trees 会展示出现一些奇怪的行为,例如影响其他在使用相同参数的 Direct Blend Trees,并且还会随着时间的推移将乘以它们的结果,导致意外结果的发生。您通常应永远不被使用这么做。
为了更清楚地说明乘法行为,此处列出最终结果是,:在 Write Defaults Off
的 Direct Blend Trees 中,最终的权重会乘以一个因子x/(1-yx)
,其中x是 x 是当前子级的权重,y是y 是其他子级的权重之和,除以当前子级的权重。请注意,如果这个分数的分母为0或 0 或更低,则数值变为无穷大且永远不会停止增加。这意味着,如果您有n个 n 个子级,并将每个子级的权重设置为 1/n,则最终结果是乘数为1, 1 ,因此这允许您使用 Write Defaults Off
的 Direct Blend Trees。然而,这并不意味着这样做就是明智的,。因此由于这会影响其他混合树和表现出其他奇怪的行为使得,您可以使用 Write Defaults On
,它更为简单。
如果您正在使用 Write Defaults Off
,则您的所有状态都应包含一个动画切片或 Blend Tree。
不包含任何动画片段的 Write Defaults Off
状态可以将会使用它们来自的 Animator State 上一个状态中的动画剪辑片段的属性默认值,覆盖先前写上方图层中的动画剪辑片段。
优点/缺点
Write Default On
优点:
- 由于可以使用空动画状态
/缓冲状态(或 buffer clip) 来恢复到默认上传行为时模型状态,因此不太复杂使用稍简单些 - 允许在 FX 层上
对使用变换动画进行变换,而且不会将动画覆盖手势写到 Gesture 层 - 在基
本2状础的双状态切换中,比相对Write Defaults Off
降低减少了33%的帧时间(在Unity 2019中) - 更容易更改默认值(如果您依赖上传时状态)
缺点:
- 依赖上传时状态
- 通常在混合使用
MixedWrite Defaults
时会出现问题 - 不允许在不使用
参数驱动程序Parameter Drivers 或 AAP 的情况下进行顺序操作
Write Default Off
优点:
- 不依赖于上传状态
- 通常与混合写入默认值兼容
- 允许顺序操作
缺点:
- 在空状态中需要缓冲动画
- 在没有遮罩的情况下对变换进行动画处理时,会覆盖所有手势变换
- 在基本2状态切换中,比
Write Defaults On
增加了50%的帧时间(在 Unity 2019中)
创作指南
当创建应与 Write Defaults On
和 Write Defaults Off
兼容的预制件时,这些指南将非常有用:
- 请确保每个图层始终通过其自身的一组属性进行动画处理(例如,图层中的每个状态都应动画化相同的一组属性)。
- 如果需要在多个图层上动画化某个属性,请确保每个状态都具有动画效果,了解较低图层会覆盖较高图层,并始终在顶部提供一个具有默认状态的“重置”图层。
如果您遵循本文档中概述的指南,每个属性都将始终动画化,并且您的系统将始终与 Write Defaults On
和 Write Defaults Off
一起正常工作。
Blendshape 值翻倍
在非常特定的条件下,当依赖于 Write Defaults On
时,Blendshape 值会翻倍。
(例如:您有一个空的 Write Defaults On
状态,它过渡到一个绘制 Blendshape 的 Write Defaults On
状态。当处于空的 Write Defaults On
状态时,绘制 Blendshape 的默认值会乘以3。)
这个问题比其他问题更加微妙和模糊,所以不要把我们在这里说的话当作事实,而更多地当作观察结果:
- 它似乎是由
Write Defaults Off
了的 Additive layer 引起的。 - 它被一个只有“关闭默认写入”状态(如默认状态)的手势层所阻止。单个播放“默认写入开启”状态会导致它再次发生。
- 它与任何遮罩和实际可到达的动画都无关。只需存在于图层上就足够了。
- 只要您使用值0-100,它就不会影响其行为,因 03=0 并且 1003=100 (因 Blendshape 钳制,您可以在 Unity 项目中通过转到 Project Settings → Player → Other Settings → Clamp Blendshapes (Deprecated) 来启用它。这在 VRChat 中已被启用。)
- 修复此问题的正确方法是始终明确设置 Blendshape 值。
- 糊弄式修复此问题的方法是设置空闲图层中的状态为
Write Defaults On
。