Unity CJ 乾貨分享:全新的Unity移動遊戲優化解決方案

在今年的CJ CGDC 中國遊戲開發者大會上,來自Unity大中華區的技術支持經理張鑫帶來了關於《全新的Unity移動遊戲優化解決方案》的精彩主題演講。本次演講分享的內容,包括從渲染模塊、物理模塊、動畫模塊的CPU優化;如何對堆內存的管理以及面對內存泄露和資源冗餘的解決方案;以及對代碼的優化處理。


CPU優化


首先通過Profiler來找到具體的瓶頸,通過Profiler可以看到每一幀裏每個函數的具體開銷。



自身邏輯代碼效率



如果我們的代碼邏輯很複雜,上萬行,那麼可以藉助Begin/EndSample 來拆分,得到真正開銷大的代碼塊。


渲染模塊效率



在移動設備上,半透明渲染的開銷是需要特別注意的(像花,樹,草等),因爲在移動設備上會造成更多的overdraw


不同的設備對Drawcall的敏感度不同,因此可以針對設備做一個“LOD”,在高端機上允許更多的drawcall(即可以開啓更多的特效等)。


動畫模塊效率



MeshSkinning.Update 是蒙皮計算的開銷,Animator.Update 是骨骼動畫的更新開銷。OptimizeGameObject的優化選項默認是關閉的。在紅米上,一個100人的測試案例中,開啓之後,前者可以提高70%的效率,而後者可以提高30%的效率。


另一個測試也是在紅米上,200人同屏,單個角色400個頂點,560面左右,動畫的總時長爲6秒,骨骼數量平均爲12個。通過序列幀的形式實現skinnedMeshRenderer到MeshRenderer 的轉換。可以跑到25幀。

BakeMesh (SkinnedMeshRenderer.BakeMesh)

  • 200+

  • ~400 頂點

  • ~500+ 60 面

  • ~6 s 動畫

  • ~12 骨骼


UI模塊效率



上圖是一個Ui的例子,由一位工程師在兩週左右的時間完成,美術除外(來自scaleform在Assetstore上的資源)。


UI系統的渲染順序是由UI元素在Hierarchy中的順序決定的。而Ui系統會通過重排UI元素的渲染順序來減少drawcall,但前提是不改變渲染結果。因此發生重疊之後,drawcall可能會上升。


內存管理


遊戲製作的中後期通常會開始遇到內存上的問題。

  • 總體內存:


•Used Total:當前幀的Unity內存、Mono內存、GfxDriver內存、Profiler內存的總和。


  • Mono內存:

  • 記錄代碼堆內存的分配情況,由Mono控制

  • 內存只增不減

  • 建議<40MB


Mono內存有80%的團隊都不太關心,但卻是很重要,會影響遊戲的流暢性。


  • 常見問題:Log輸出

StackTraceUtility.PostprocessStacktrace ()

StackTraceUtility.ExtractStackTrace()


Log的輸出不僅會消耗CPU,同時也會引起較大的堆內存分配。


  • 內存泄露

  • 資源被強行Hold無法釋放

  • 表現症狀:Profiler中內存增長趨勢明顯,且資源無法回收

  • DetailedMemory Profiler


  • 資源冗餘

  • 資源通過AB加載,且資源在AB建立時存在多份

  • 對AB打包機制進行詳細排查

  • 依賴關係打包



代碼優化


  • 遊戲優化深度檢測:

  • 通過Profiler逐幀查看和分析CPU佔用較高的函數


  • GC.Alloc


  • Shader.Parse

  • Shader加載時的解析耗時


這部分耗時的避免,可以通過將shader打入單獨的assetbundle包,並在進入場景時就進行預加載。


同一時間Load過多的非“基礎”AB,且不及時Unload,會導致過多的內存消耗,如WebStream 和Serialized File 的內存。


而PersistentManager.Remapper 的意義是:PersistentManager維護資源的持久化存儲功能,Remapper保存的是加載到內存的資源heapID與源數據FileID的映射關係,但Remapper是memory pool,只增不減,因此建議不要一次性加載過多的assetbundle,而是以流式的方式來加載,以減小其峯值。


小結:性能優化是沒有定式的,它需要“因時因地”制宜。

發佈了30 篇原創文章 · 獲贊 12 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章