Skip to main content

使用混合树来合并多个动画层

原文出处:https://notes.sleightly.dev/dbt-combining/

由于 Animator Controller 中 Animator Layers 对性能的影响较大,一个对性能更友好的做法是通过使用 Direct Blend Tree 将切换开关和转轮开关等功能合并到同一个 Animator Layer 中。

译者注释:转轮开关指的是一种圆形的轮盘菜单操作模式,通过类似进度条的菜单来控制一个数值从 0% - 100%

理解什么是 Direct Blend Trees

Direct Blend Trees 允许你为其内的每一个 Animation 或 Blend Tree 分支设置参数。这让你能够在同一个 Blend Tree 中同时控制多个动画。

译者注释:有时候 Direct Blend Trees 也被称为 DBT

对于 VRChat,我们可以利用这一特性,在单个 Direct Blend Tree 中制作多个切换开关和转轮开关,类似于在多个动画层中进行的操作。

Direct Blend Tree 的结构和功能与 Animator Controller 非常相似,因此将它们视作 Animator Controllers 可能会更容易理解。这是一种简化的理解 Direct Blend Trees 的方式,但需要注意的是,尽管它与 Animator Controllers 非常相似,但并不完全相同!

两者之间存在一些关键差异,这些差异在很大程度上限制了 Direct Blend Trees 的使用场景和实现方式。有关更多信息,请参阅“限制和已知问题”部分。

image.png

一个包含 3 个服装组件切换开关的 Direct Blend Tree

译者注释:
  • Layer Weight:层级权重
  • Parameters:参数
  • Transitions:过度
  • Animator Controller动画器
  • Layers:层
  • States:状态

 

创建切换开关和转轮开关

在 Direct Blend Tree 中制作切换开关和转轮开关与在 Animator Layer 中制作常规切换开关并无太大区别,也不会更为复杂。

 

步骤 1

  • 创建一个新的 Animator Layer,然后在空白区域右键点击以创建一个新的 Blend Tree State。

image.png

  • 将 Blend Tree State 的 Write Defaults 值设置为 ON!这是必要步骤!我们会在 Write Defaults 部分详细说明原因。

译者注释:无论你的其他动画层是否使用 Write Default,只要你的这个动画层只有这一个Direct Blend Tree并且只有这一个 State,在这样的情况下单独启用 Write Default 不会影响你的动画器,也不会造成任何问题无需担心启用 Write Default会造成问题。

 

image.png

步骤 2

  • 双击或右键点击 Blend Tree State 来打开它。
  • 选择 Blend Tree,然后在检查器中将 Blend Type 更改为 Direct

    image.png


步骤 3

  • 将一个新的 Blend Tree 作为子项添加到 Direct Blend Tree 中。
  • 如果还没有,创建一个新的 float 参数(例如 Weight),并将值设置为 1。
    • 这个参数不是用于切换开关本身的参数,而是一个独立的参数,用于将子项的权重设置为 1,以便它能被完全控制,类似于你将 Animator Layer 的权重设置为 1。
  • 将子项的参数设置为这个 float 参数。
    • 你可以为所有子项重复使用这个 float 参数,无需为每个子项创建新的参数。
  • 确保 Direct Blend Tree 的 Normalized Blend Values 没有勾选。

image.png

步骤 4

  • 选择子项 Blend Tree,确保 Blend Type 设置为 1D
    • 你可以在窗口顶端重命名 Blend Tree 以便于管理。
  • 为你正在制作的切换开关或转轮开关创建一个新的 float 参数,并将其设置为当前子项 1D Blend Tree 的参数。
  • 为该子项 1D Blend Tree 中添加两个新的动画,并放入你通常用于切换开关或 1D 转轮开关的动画。
    • 如果你习惯使用 Motion Time 的单个动画来制作转轮开关,你需要将动画修改成成适合 1D Blend Tree 的转轮开关形式。

仅使用一个动画片段(如 WD On 工作流程中那样)是行不通的!你需要单独的动画或一个合并动画。

译者注释:合适 1D Blend Tree 的动画指的是,例如你的动画有4个帧,对应4套服装的开启,那么你需要将这4个帧做成4个独立的动画,每个动画控制一套服装的开启,这样才能分散在 1D Blend Tree 上。传统的 Motion Time 式做法不能在 Blend Tree 中直接套用。


image.png

步骤 5

  • 将 1D Blend Tree 使用的参数添加到你的 VRChat Expression Parameters List 中。
    • 如果你正在制作转轮开关,将类型设置为 float
    • 如果你正在制作切换开关,将类型设置为 bool
      • 由于 参数类型不一致 的行为,这样设定也可以正常工作。

译者注释:如果你的设计中具有多余2个状态,将不合适 参数类型不一致 的做法,你需另外设计一个合适的方法来驱动。

image.png

  • 重复以上步骤来制作所有需要的切换开关和转轮开关,你可以这样制作任意数量的开关。

image.png


写入默认(Write Defaults)

在处理写入默认(Write Defaults)时,Direct Blend Trees 是一个例外。它的 Write Defaults 值可以和 Animator Controller 的其他部分的设定不同,这意味着你可以混合使用 Write Defaults,只要不在同一个动画层中混用即可。

对于 Direct Blend Trees 来说,即使 Animator Controller 的其他动画层使用 Write Defaults Off,我们也可以安全地使用 Write Defaults On。能够在 Direct Blend Trees 使用 Write Default On 可以帮助我们避免以下 Write Default Off 的 Blend Tree 具有的问题:

Write Defaults Off 的 Direct Blend Trees 的问题:

  • 权重必须标准化
  • 动画控制的属性值必须
  • 使用多个 Blend Trees 时不稳定
  • 输出结果会被"平滑化"
  • 不能用动画作为第一分支

因此,不建议使用 Write Defaults Off 的 Direct Blend Trees,因为它们比 Write Defaults On 的版本更不稳定且更难以处理。即使 Animator Controller 的其他部分使用 Write Defaults Off,使用 Write Defaults On 的 Direct Blend Trees 也是完全安全的。

译者注释:无论你的其他动画层是否使用 Write Default,只要你的这个动画层只有这一个Direct Blend Tree并且只有这一个 State,在这样的情况下单独启用 Write Default 不会影响你的动画器,也不会造成任何问题无需担心启用 Write Default会造成问题。

你可以在 Blend Tree 的名称前添加前缀(WD On),这样在使用 https://github.com/VRLabs/Avatars-3.0-Manager 批量设置 Animator Controllers 的 Write Defaults 值时不会受到影响。

这对于希望确保他们产品的用户在使用类似工具时不会意外关闭 Write Defaults 的 Avatar 和 Prefab 创作者特别有用。

将 Write Defaults 值从 On 更改为 Off 将会使得 Blend Tree 出错,直到 Write Defaults 被设置为 On!

image.png

嵌套 Direct Blend Trees

如果你有很多切换开关和转轮开关,你的 Direct Blend Tree 可能很快就会变得庞大且难以管理。你可以通过将 Direct Blend Trees 嵌套在一起,模拟文件夹的结构,从而提高组织性

如果你在嵌套之前已经创建了所有的切换开关和转轮开关,你需要把他们全部删除,然后在文件夹里重新制作,因此最好预先考虑好这一点(除非你有工具可以重新排列 Blend Trees)。

译者注释:确实有一个美妙的工具可以重新排列 Blend Trees,但是纸张的空间太小了,就不在此多赘述了

如图所示,我们有一个包含九个子项的 Direct Blend Tree。我们可以通过利用更多的 Direct Blend Trees 将它们组织成文件夹。

image.png

首先,你想制作几个文件夹,就新建几个 Blend Tree,方法与创建切换开关或转轮开关时相同。

接下来,选择每个子项,并在检查器中将 Blend Type 更改为 Direct。

image.png

然后,按照前文所述的办法制作切换开关和转轮开关,只不过现在你是在文件夹内部制作。

为了更方便维护,你还可以选中文件夹,然后在检查器顶部重命名这些文件夹。

你可以给子文件夹设置和根 Direct Blend Tree 的相同 Weight 参数,如前文第3步所述。

有关将多个转轮开关和切换开关合并在一起的示例,请参见 Direct Blend Tree Radials and Toggles (Nested)

image.png

你可以双击任何一个 Direct Blend Tree 来在一个独立窗口中打开它,这在你的 Blend Tree 规模巨大,以至于出现性能问题的时候尤其有用。

image.png

你可以通过点击左上角的箭头返回到完整的 Blend Tree 视图。

image.png


进阶 Blend Tree 技术

Blend Trees 的应用远不止简单的切换开关和转轮开关,还包括:

  • 执行基本的数学运算,如加法、减法和乘法
  • 解决数学方程,例如基本的指数平滑
  • 模拟逻辑门,如 AND、OR 和 XOR 门

截至目前,这些技术相对缺乏详细文档,超出了本指南的范围。

如果需求足够大,未来可能会添加相关的扩展文章。


当前限制和已知问题

  • 目前对于动画切换,如溶解切换以及 Motion Time 等没有令人满意的解决方案。
  • 对于驱动其他参数,例如排他性切换需要使用 Parameter Driver,也没有令人满意的解决方案。
  • 首次运行 Blend Tree 时,动画属性的值可能会在一帧内被设置为 0。

译者注释:排他性切换指的是,例如有3套服装,同时间只应该启用一个,而不是有2个或3个同时启动用。例如 Int 天然的具备排他性,但你不能直接在 Direct Blend Trees 中使用整数。一些特性需要设计额外的功能模块或者逻辑才能在 Direct Blend Trees 中使用。