Optimized GameObject時到底發生了什麼

  • 問題: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面板進行配置就可保留相關掛點。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章