Foxlair

通过hack yaml文件实现串接不同的blendTree

· q8f13

之前曾遇到情况 有两个BlendTree A和B 其中B已经做了大量的配置和调试工作 而后来发现希望能将B作为A的一个混合条件存在

Unity中并没有提供将某个BlendTree子节点直接引用到其他的blendTree的功能 这样一来,如果要达到要求,那么之前B上许多的配置和调试都浪费了 于是研究下有没有办法能做到不做重复劳动

Unity的Animator controller文件和其他常见文件一样,都是以yaml格式存储的 这就说明理论上所有的文件配置内容都可以通过修改yaml文件达到目的 于是顺着这个思路开始

发现controller中,BlendTree的存储存在着这样一种固定格式:

1--- !u!206 &XXXXXXX
2BlendTree:
3  m_Childs:
4  - serializedVersion: 2
5    m_Motion: {fileID: xxxxxxx}
6    xxx
7  - serializedVersion: 2
8    m_Motion: {fileID: 0}
9    xxx

经过观察可以发现,fileID为0,对应的是blendTree中的motion field
而fileID不为0的,则是某个BlendTree的节点,其id能在yaml中找到

这么一来,能不能直接强行将blendTree B本身的节点作为blendTree A的某个子节点嵌入呢? 于是,我们首先找到blendTree A的相关配置位置,在其m_Childs下照猫画虎地添加一段:

1  - serializedVersion: 2
2    m_Motion: {fileID: 0}
3    m_Threshold: 1
4    m_Position: {x: 0, y: 0}
5    m_TimeScale: 1
6    m_CycleOffset: 0
7    m_DirectBlendParameter: Blend
8    m_Mirror: 0

然后,我们找到blendTree B的相关信息

 1--- !u!206 &206564827557635720
 2BlendTree:
 3  m_ObjectHideFlags: 1
 4  m_PrefabParentObject: {fileID: 0}
 5  m_PrefabInternal: {fileID: 0}
 6  m_Name: B_Stage1
 7  m_Childs:
 8  - serializedVersion: 2
 9    m_Motion: {fileID: 0}
10    m_Threshold: 0
11    m_Position: {x: 0, y: 0}
12    m_TimeScale: 1
13    m_CycleOffset: 0
14    m_DirectBlendParameter: Blend
15    m_Mirror: 0
16....

&206564827557635720这串ID中,’&‘后面的部分即为该blendTree的ID了
于是我们将这个ID直接嫁接到上面blendTree A的子节点中,粘贴到某个子节点的fileID上

1  - serializedVersion: 2
2    m_Motion: {fileID: **206564827557635720**}
3    m_Threshold: 1
4    m_Position: {x: 0, y: 0}
5    m_TimeScale: 1
6    m_CycleOffset: 0
7    m_DirectBlendParameter: Blend
8    m_Mirror: 0

保存后,重新回到Unity,会发现A的子节点中多了个B,之前B的所有配置内容都完整保留下来了 大功告成

#unity   #animator