您的位置:首页 > 移动开发 > Objective-C

Optimized GameObject时到底发生了什么

2018-01-11 14:35 776 查看
问题:Optimize前后生成的prefab结点数量发生了明显的变化,容易让人误以为骨骼空结点只是展示看的,但是如果直接删除空结点就会发现蒙皮动画出现错误。所以问题就是, Optimize的时候发生了什么?Unity做了什么修改?

尝试1:查看UnityEditor.Dll里的代码,Apply Optimized GameObject时仅仅修改了m_ExtraExposedTransformPaths的内容

尝试2:查看使用和不使用Optimize生成的Prefab有什么不同

- Optimized之后的prefab:

m_Bones: []


m_RootBone: {fileID: 0}


- 不Optimized的prefab,这里的FileID对应的是Prefab内部的骨骼结点

m_Bones:

-{fileID: 4136033779980552}

-{fileID: 4068391989916132}

-{fileID: 4929649166801780}

-{fileID: 4756659351305440}

-{fileID: 4146386435630952}

-{fileID: 4992511966160680}

m_RootBone: {fileID: 4929649166801780}


初步结论:m_Bones决定了SkinnedMeshRenderer是否操纵Prefab内的骨骼结点

实验推证:清空没有Optimized的m_Bones并修改Animator的私有属性HasTransformHierarchy,可成功的将其转为完全Optimized的效果!

疑惑:打印SkinnedMeshRenderer的bones数量,发现Optimized之后的的Prefab的bones数量是0!可是既然没有骨骼信息,蒙皮是怎么动起来的呢?

接着实验:去掉Animator的Avatar组件,发现Optimized过的模型立刻停止了工作,而非Optimized的模型删除掉Avatar还在继续运动,可以看出来Optimized过的模型中Avatar起到了关键的作用。

换个角度:SkinnedMeshRenderer是如何取得骨骼的信息的(权重、顶点),这些信息是怎么组织的?

继续实验:从Fbx文件里面取出来Mesh,发现Mesh具有Skin信息,包含骨骼、权重、索引等信息。但是没有骨骼的名称,只有名称的Hash值信息。可以推断,在Optimized之后,Animator的hasTransformHierarchy为false,即Animator不再根据Transform骨骼的位置当作信息,而是根据Avatar作为中间层,转发AnimationClip中对骨骼的控制至Mesh的蒙皮过程。

最终结论

- 非Optimized的情况下:Animator的hasTransformHierarchy为true,此时根据fbx生成的Prefab内m_Bones包换完整的信息以及对应的Transform层级结点。当运行时,Animator通过修改Transform的位置来控制蒙皮的运动。此时Avatar并没有真正的被使用。

- Optimized的情况下:Animator的hasTransformHierarchy为false,此时根据fbx生成的Prefab内m_Bones为空,且不再具有完整的Transform节点,所有需要被保留的骨骼节点都成为父物体的直接子物体。当运行时,Animator通过Avatar做映射驱动被保留的节点进行蒙皮。Avatar此时必不可少,因为其包含了骨骼的ID,AnimationClip播放时修改对应ID骨骼的信息,而Avatar将ID转发给SkinnedMeshRenderer,SkinnedMeshRenderer根据ID找到SkinnedMesh中对应的信息,进而重新计算整个蒙皮的信息。在Awake时,将寻找Prefab下同名骨骼,发现则绑定为保留的骨骼,因此甚至不需要在FBX面板进行配置就可保留相关挂点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity 动画