Unity Write Default Bugs
目录
Unity 动画控制器中 WriteDefault 问题的整理
关于这篇文章
本文为 Unity 动画控制器中 WriteDefault 问题的整理,用于 VRChat 改模参考, 目前的内容来自 Write Default Bugs in Unity | VRCFury
Unity 中的 Write Defaults 问题
Write Defaults (写入默认值) 会导致大量未记录的 Unity Bug,其中许多问题至今仍在被发现。以下是我们目前已知的问题:
混合 Write Defaults
条件:
- 控制器包含 Write Defaults (WD) 开启和关闭的混合状态
- 一个 WD 关闭的状态位于包含 WD 开启状态的层中或之下
结果:
- 控制器中的随机属性将“粘住”,即使动画指示它们改变,它们也拒绝更改。
可能的解决方法:
- 不要在控制器中混合使用 WD(除非在直接 BlendTree 和 Additive 层中,这些地方必须始终开启 WD)
- 如果必须混合使用,请确保所有 WD 开启的状态位于 WD 关闭状态的下方
- 请注意,在 VRChat 头像中,所有可播放层控制器都被视为一个“控制器”
直接 BlendTrees 和 Additive 层的 WD 关闭
条件:
- 包含直接 BlendTree 的状态或 Additive 层中的状态设置为 WD 关闭
结果:
- 控制器中的随机属性可能每帧增长或缩小,导致它们无限制地偏离
- 在控制器中动画的 BlendShapes 可能会意外地乘以 2 倍或 3 倍
可能的解决方法:
- 确保所有直接 BlendTrees 和 Additive 层中的所有状态始终开启 WD
WD 关闭时无掩码控制器中的变换
条件:
- 混合器中的多个控制器使用 WD 关闭(例如 Gesture 和 FX)
结果:
- 混合器中最低的控制器(通常是 FX)将宣称所有未掩码的变换的所有权
- 即使这些变换在控制器中的任何状态中都没有动画,它仍将阻止混合器中的任何更高控制器对它们进行动画处理
可能的解决方法:
- 使用 WD 开启
- 合并 Gesture 和 FX,这样 FX 宣称所有变换是可以接受的(因为所有变换动画都在一个控制器中)
- 为 FX 添加掩码,防止其拥有特定变换(在某些情况下由于掩码层中的属性破损而无法实现)
WD 关闭或开启时无掩码控制器中的肌肉
条件:
- 混合器中的多个控制器对同一人形肌肉进行动画处理
结果:
- 混合器中最低的控制器(通常是 FX)将宣称所有未掩码的肌肉的所有权
- 即使这些肌肉在控制器中的任何状态中都没有动画,它仍将阻止混合器中的任何更高控制器对它们进行动画处理
可能的解决方法:
- 确保每个肌肉只由一个控制器进行动画处理
- 如果需要覆盖,使用 Playable Layer Control 在动画完成时将覆盖控制器的权重设置为 0(如在 Action 中所做的那样)
WD 关闭时无掩码层中的肌肉
条件:
- 单个控制器中的多个层使用 WD 关闭
- 两个层对人形角色的同一肌肉进行动画处理
结果:
- 最低的层在第一次对肌肉进行动画处理时“宣称”肌肉的所有权,阻止任何更高的层对该肌肉进行动画处理
- 移动到不再对肌肉进行动画处理的状态不会释放所有权
可能的解决方法:
- 使用 WD 开启
- 使用 Animator Layer Control 将较低层的权重设置为 0
掩码层中的属性破损
条件:
- 状态的层或控制器的基础层包含一个不允许所有变换的掩码
结果:
- 状态无法对材质槽 0 进行材质交换,如果它不在掩码中允许的变换内
- 状态无法对大于 0 的材质槽进行材质交换
- 状态无法对 VRC Physbone(以及可能的其他非标准组件类型)进行属性动画处理
可能的解决方法:
- 不要在层或控制器的基础层上使用掩码
WD 关闭时的空动画
条件:
- 状态使用 WD 关闭
- 状态在根运动或任何 BlendTree 子项中包含“无”动画或空动画剪辑
结果:
- 类似于混合 WD 的症状
可能的解决方法:
- 如果状态使用 WD 关闭,确保所有运动和 BlendTree 子项都设置为包含至少一个属性的动画剪辑(它不必有效)
WD 开启时的混合不是加法的
条件:
- WD 开启
- 一个层中的动画剪辑设置了一个属性
- 在较低层的 BlendTree 中以部分权重 >0 修改了相同的属性
结果:
- 最终属性值不考虑第一个层中的值
例如:
- 如果属性的默认(静止状态)值为 0
- 属性在层 1 中被动画设置为 5
- 属性在层 2 中以 0.1 的权重被动画设置为 10
- 最终值将是 1(完全忽略了 5)
- 然而,如果层 2 的权重被更改为 0,最终值突然变为 5
可能的解决方法:
- 不要在多个层中动画相同的属性,如果它们涉及“开放式”混合
- 所有涉及在较高层动画的属性的 BlendTrees 都应完全动画所有子项中的共享属性
- 涉及在较高层动画的属性的直接 BlendTrees 应始终具有权重 1(完全动画)或 0(传递到上层)
WD 开启时,过渡到 BlendTrees 的时间中断
条件:
- WD 开启
- 动画中的任何参数由动画控制
- 一个状态过渡到另一个使用 BlendTree 的状态,当前混合涉及多个运动
结果:
- 过渡忽略了正在过渡的状态,立即跳到新状态
可能的解决方法:
- 使用 WD 关闭
- 完全避免这种情况(不要在多状态层中使用 BlendTrees)
- 不要使用动画参数(通常无法避免)