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:
- 不Optimized的prefab,这里的FileID对应的是Prefab内部的骨骼结点
初步结论: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面板进行配置就可保留相关挂点。
尝试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面板进行配置就可保留相关挂点。
相关文章推荐
- 当你的iPhone收到推送信息后到底会发生什么呢?
- Https:从tcp建立连接到https接收到第一个数据包,到底发生了什么?
- 当执行[object selector:para]的时候,发生了什么?
- 从输入 URL 到页面展示,到底发生了什么
- 当你的iPhone收到推送信息后到底会发生什么呢?总共有三种可能性
- 从输入 URL 到页面展示,到底发生了什么
- 从输入url到页面展示到底发生了什么
- C++中include头文件到底会发生什么事?
- .NET 3.5框架中到底发生了什么巨变?
- linux 终端下敲ctrl-c时,到底发生了什么?
- 老生常谈-从输入url到页面展示到底发生了什么
- $(".class")后到底发生了什么 -- jquery选择器分析
- Js new到底发生了什么
- 从浏览器输入网址到显示网站页面之间到底发生了什么?系列(一)
- WorkerMan学习篇:连接mysql时到底发生了什么鬼
- 从输入url到页面展示到底发生了什么(面试常题)
- 从输入url到页面展示到底发生了什么,转载大神的
- 【原】老生常谈-从输入url到页面展示到底发生了什么
- 一次URL输入域名按下回车到底发生了什么?
- java 字符串使用+号的时候 到底发生了什么