【求知探新】是UWA新推出的栏目。在UWA团队做性能优化的过程中,常常会遇到一些未知的问题,在这里我们将分享UWA研究这些问题的完整过程。当然需要说明的是,一个好的问题没有标准的答案,在此也欢迎大家来积极拍砖!
今天的分享来自UWA问答社区(answer.uwa4d.com),ID为徐琨的朋友发现是否勾选Optimize GameObject会影响骨骼的朝向。为此,UWA技术团队通过对提问者提供的例子进行反复测试、剖析了导致该问题的原因,并将分析过程和解决方案在此分享。
一、问题描述
相同的角色FBX,一个使用Optimize GameObject选项并暴露相应的骨骼,一个不使用,分别创建各自的Prefab,播放相同动画后,发现同一骨骼的朝向不一致(但位置是一致的)。
二、问题复现
我们使用研发团队提供的Package中的模型,复现了该问题。播放相同动画时,sk_palm_I的朝向如下图:
左:使用 Optimize, 右:不使用 Optimize
三、问题分析
我们首先进行一系列实验,试图从例子中发现一些有用的线索。
1. 我们将更多的骨骼暴露出来,来看是否所有的骨骼朝向都不相同。结果发现,朝向不同的骨骼只是个例,进而发现sk_palm_I这根骨骼不存在对应的动画曲线,并且没有蒙皮对应的顶点。暴露其他没有动画曲线和蒙皮顶点的骨骼,发现骨骼朝向也不相同。
2. 再来对比骨骼的朝向,发现不开启Optimize选项的sk_palm_l的transform.rotation(相对父骨骼)保持不变,手动将其设为(0,0,0)后朝向与开启Optimize选项的sk_palm_l朝向一致。因此,我们推测Optimize选项后无动画的骨骼的Rotation被归零,在其他无动画的骨骼上得到验证。
3. 发现朝向不一致问题的角色使用了Humanoid模式,将其切换至Generic模式观察骨骼朝向。然后发现,在Generic模式下,不管骨骼有无动画曲线,其开启Optimize前后的朝向都是一致的。这说明朝向不一致问题只出现在Humanoid模式下。
通过这些实验,可以得出骨骼朝向不一致的条件:Humanoid模式,骨骼没有对应的动画曲线和蒙皮顶点。而开启Optimize后的朝向是开启前对应骨骼的Rotation归零后的朝向。
参阅 Unity关于Humanoid 以及 Optimize选项的相关描述:
Humanoid会将骨架(Skeleton)信息映射到另一个空间(通过Configure Avatar)。开启Optimize选项后,Unity更新骨骼矩阵时将不再考虑场景中骨骼Transform,而是直接使用Internal Skeleton。
综合上述这些信息,我们推测Humanoid的映射过程中骨骼Transform信息发生了变化。骨架映射可以在Configure Avatar中设置。下图验证了我们的想法:
在映射时,sk_palm_I的Rotation已经归零。
发现了问题原因,解决方法就很明了,在映射时修正Rotation信息。通过Pose->reset,所有骨骼的Transform就会与原始骨骼的Transform一致。然后再Enforce T,来进行映射。之后开启Optimize GameObject前后的骨骼朝向基本一致,问题解决!
四、结论
Pose->Biped Pose(默认)会把所有不带动画、没有蒙皮顶点且不在Muscle中的骨骼的Rotation归零,所以对于类似该案例中的这类模型,映射时需要Reset。这个问题也验证了在开启Optimize GameObject之后,场景中的骨骼Transform信息不再影响到骨骼矩阵运算,也就省略了Mono到Native的信息传递,因此会使骨骼矩阵运算的速度得以提升。所以建议开发团队尽量地开启该选项。