写入默认值(Write Defaults)
概述
Write Defaults
(写入默认值)是动画状态中的一个选项,也是许多虚拟形象创作者的头痛之源,因为它们的行为常常出乎意料且难以理解。其预期行为如下:
Write Defaults
(写入默认值)字段决定此动画所做的更改是否持久化。
-
如果启用了
Write Defaults
(写入默认值),则在离开动画状态时,动画字段将返回到其默认状态。 -
如果禁用了
Write Defaults
(写入默认值),则更改将保持不变。
默认情况下,Unity 会在新创建的状态上启用 Write Defaults
(写入默认值),但 VRChat 提供的示例动画控制器是写入默认值关闭的。
默认的动画状态,默认启用写入默认值。
示例:
如果你有一个帽子,在上传过程中默认是禁用的(即默认关闭),并且你有一个如下所示的层:
在 Write Defaults On
(写入默认值启用)的情况下:
-
当进入帽子开启状态时,帽子会启用。
-
当返回到空状态时,帽子会关闭(因为默认状态被写回)。
在 Write Defaults Off
(写入默认值关闭)的情况下:
-
当进入帽子开启状态时,帽子会启用。
-
当返回到空状态时,帽子会保持启用状态(因为你没有显式地将其关闭或写回默认值)。
指南
在使用 Write Defaults Off
(写入默认值关闭)时,需要遵循一些指南。以下是这些指南及其存在的原因:
-
不要在单个控制器中混合使用
Write Defaults Off
(写入默认值关闭),混合使用写入默认值会导致所有Write Defaults On
(写入默认值启用)的状态无法写入其默认值,从而表现得像写入默认值关闭一样。- 唯一的例外是仅包含单一状态的层。这些层可以(并且在直接混合树的情况下,应该)设置为写入默认值启用。
- 这样做是可以的,因为它们永远不会离开其状态,因此我们永远不会依赖写入默认值启用的行为。
-
不要在 Direct Blend Trees(直接混合树)上使用
Write Defaults Off
(写入默认值关闭) -
如果使用
Write Defaults Off
(写入默认值关闭),所有状态都应包含动画片段或 Blend Tree,这些动画片段可以是空的,但通常建议使用一个动画片段(Animation Clip)来动画化一个不存在的游戏对象(有时称为缓冲片段)。 -
注意:使用
Write Defaults Off
(写入默认值关闭)的变换动画会覆盖其他正在播放的动画控制器中的所有变换动画。具体来说,对于 VRChat,如果你在 FX 层中动画化任何变换,它将覆盖手势层中的所有变换,除非你应用一个 Avatar Mask(虚拟形象遮罩),仅启用动画化的变换并禁用其他所有变换,并将此遮罩应用于你的 FX 层动画层。有关遮罩的更多信息,请参阅虚拟形象遮罩页面。
如果你由于手势层和 FX 层中的写入默认值关闭变换动画而必须使用遮罩,则除了第一个插槽外,你不能在任何插槽上使用材质替换,因为遮罩的变换(无论是启用还是禁用)除了第一个材质插槽外,不能有动画化的材质替换。
一个有用的工具是 VRLabs’ Avatar 3.0 Manager,它可以帮助你检查是否违反了这些规则(至少是第一条和第三条)。在该工具的写入默认值选项卡中,它会告诉你是否混合使用了写入默认值,并在你按下相应按钮时为你设置。请注意,它不会对直接混合树做例外处理,因此它们的动画状态名称中必须包含 (WD On)
以标记为写入默认值启用。
一个确保没有空状态的动画片段示例。
解释
不要在单个控制器中混合使用 Write Defaults(写入默认值)
播放一个 Write Defaults Off
(写入默认值关闭)的状态会导致所有其他 Write Defaults On
(写入默认值启用)的状态无法写入其默认值,从而表现得像 Write Defaults Off
(写入默认值关闭)一样。
不要在直接 Blend Tree(混合树)上使用 Write Defaults Off(写入默认值关闭)
使用 Write Defaults Off
(写入默认值关闭)的直接混合树会表现出奇怪的行为,例如影响其他使用相同参数的直接混合树,并且随着时间的推移会叠加结果,导致意外行为。通常应避免使用。
为了更清楚地解释这种乘法行为,最终结果是,在 Write Defaults Off
(写入默认值关闭)的混合树中,最终权重会乘以一个因子 x/(1-yx),其中 x 是当前子节点的权重,y 是其他子节点权重之和除以当前子节点的权重。需要注意的是,如果这个分数的分母为0或更小,值将趋向于无穷大,并且永远不会停止叠加。这意味着,如果你有 n 个子节点,并且将每个子节点的权重设置为 1/n,那么最终结果将是乘数为1,因此这允许你使用 Write Defaults Off
(写入默认值关闭)的直接混合树。然而,这并不意味着建议这样做,因为影响其他混合树以及其他奇怪的行为使得直接使用 Write Defaults On
(写入默认值启用)更加简单。
使用写入默认值关闭时,所有状态都应包含动画片段或混合树
没有动画片段的 Write Defaults Off
(写入默认值关闭)状态可能会用其默认值覆盖前一层中的动画片段。
优缺点
Write Defaults On(写入默认值启用)
优点:
-
更简单,因为你可以有空状态/缓冲状态,这些状态会回退到默认的上传行为。
-
允许在 FX 层上进行变换动画而不会覆盖手势层。
-
在 Unity 2019 中,基本的两状态切换帧时间减少 33%。
-
更容易更改默认值(如果你依赖上传状态)。
缺点:
-
依赖上传状态。
-
通常在使用混合写入默认值时会出问题。
-
不允许在没有参数驱动器或 AAP 的情况下进行顺序操作。
Write Defaults Off(写入默认值关闭)
优点:
-
不依赖上传状态。
-
通常可以很好地处理混合写入默认值。
-
允许顺序操作。
缺点:
-
需要在空状态中使用缓冲动画。
-
在没有遮罩的情况下动画化变换时,会覆盖所有手势层的变换。
-
在 Unity 2019 中,基本的两状态切换帧时间增加 50%。
创作者指南
这些指南在创建应同时兼容 Write Defaults On
(写入默认值启用)和 Write Defaults Off
(写入默认值关闭)的预制件时非常有用:
-
始终让每一层只动画化一组属性(例如,层中的每个状态都应动画化相同的属性集)。
-
如果需要在多个层上动画化一个属性,请确保每个状态都有一个动画,知道较低的层会覆盖较高的层,并始终在顶部有一个带有默认状态的重置层。
如果你遵循本文中概述的指南,每个属性都会被动画化,你的系统将始终适用于 Write Defaults On
(写入默认值启用)和 Write Defaults Off
(写入默认值关闭)。
Blendshape(混合形状)值三倍化
在非常特定的条件下,混合形状值在使用 Write Defaults On
(写入默认值启用)时会变为三倍。
(例如:你有一个空的 Write Defaults On
(写入默认值启用)状态,它过渡到一个动画化混合形状的 Write Defaults On
(写入默认值启用)状态。在空的 Write Defaults On
(写入默认值启用)状态中,动画化 Blend Shape 的默认值会被乘以 3)。
这个问题比其他问题更复杂且不太明确,因此不要将我们在这里所说的视为事实,而应视为观察结果:
-
它似乎是由
Write Defaults Off
(写入默认值关闭)的叠加层引起的。 -
它可以通过仅包含
Write Defaults Off
(写入默认值关闭)状态的手势层(如默认层)来阻止。一个正在播放的Write Defaults On
(写入默认值启用)状态会再次导致此问题。 -
它与任何遮罩以及动画是否可达无关。只要存在于层上就足够了。
-
只要你只使用值 0 和 100,它不会影响行为,因为 03=0 和 1003=100(由于 Clamp Blendshapes(钳制混合形状),你可以在 Unity 项目中启用此功能:项目设置 → 玩家 → 其他设置 → Clamp Blendshapes(钳制混合形状)(已弃用)。这在 VRChat 中是启用的)。
- 正确的修复方法是始终显式地动画化混合形状值。
- 一个快速但不完美的修复方法是将空闲层中的状态设置为
Write Defaults On
(写入默认值启用)。
No Comments