UnityIn這次整理了一些程式人員在UNITY開發上與“效能”相關,需要注意的“關鍵點”:
- 暫存常用的Component:
根據官方文件的描述,每次GetComponent的呼叫,UNITY都會花點時間尋找所要求的object上。要省下這點時間,建議利用Private變數在Object Awake時,將常的用component暫存下來。
- 不要在任何Update的function內,使用Find:
GameObject.Find這個函式用來搜尋全域、特定名稱之物件,效能上有一定的損耗,所以請盡量在Start或Awake裡使用,而非Update函式裡。若要每個Frame搜尋請改用GameObject.FindWithTag。
- 多多使用BuildIn Array:
如果物件數量是固定的,type[]的寫法是速度最快的選擇
- 運算少用“除”,多用“加、減、乘”, 根據UNITY官方數據 :
“除法”,需要30 - 40 cycles來完成
“加、減、乘”,只需要一兩個cycles
“平方根、Sin、Cos” ,需要60 - 100 cycles來完成
- 單純比較向量距離,少用Normalize:
Normalize = vec / sqrt( vec.x^2 + vec. y^2 + vec. z^2),所以盡量改用sqrMagnitude
- 少用Dynamic typing (JavaScript):
使用static typing可以讓JavaScript的程式碼跑起來跟C#一樣快。依據官方數據,JavaScript在UNITY裡的執行速度是一般C++的50%、比Mozllia JavaScript快20倍。
- 只Update在畫面上或距離較近的物件,最好在需要時才開啟enable
- 多使用Trigger或Event delegeate來觸發或通知狀態的改變,而非每個每個Update作檢查
- 盡量避免每個Frame作Raycasting:
對於Mesh物件作Raycasting有一定的Cost, 所以盡量避免每個Frame作Raycasting,可用Culling (Layer) mask先濾掉不必要的物件
- 別忽視SkinMesh與DrawCall的傷害:(Mobile Platform)
目前iPhone 3GS與Nexus One以下的機種,對於SkinMesh與DrawCall的數量還是相當敏感。以手邊的測試數據來看,800面數的角色在NEXUS ONE同一畫面上,維持30FPS可撐7~9隻角色 - 少用Alpha testing,多用Alpha Blending:(Mobile Platform)
依據PVR所公佈的數據,在iPhone 3GS以前的機種GPU的設計上,Alpha Testing是比Alpha Blending昂貴的
- 減少動態光照: (Mobile Platform)
不管是Vertex或PerPixel Lighting,都會在DrawCall上增加數量,因此對於較低階的機種會有影響。PixleLight的部分,因為是對每個Pixel做光照計算,對GPU的影響會更勝Vertex Lighting。解決方法是將光bake到貼圖上。
- 將Mesh compress壓縮比調整到最高以降低容量:
除非發現壓縮之後的Mesh出現,如:破洞、閃爍...等問題,不然盡量將這個選項設定的越高越好
- 手動呼叫gabage collection:
在固定時間間隔下手動呼叫System.GC.Collect(),確保記憶體的回收,如下:
if( Time.frameCount % m_frameFreq == 0 )
System.GC.Collect();
這個用法在Profiler下,可能會發現在CPU Cost上固定間隔的突波,但實際在手機上測試時,對於FPS並沒有顯著的影響。
如果各位先進覺得還有其他可以補中的點,也歡迎告訴我們,讓這篇文章更具指標性喔!!謝謝
作者:Bric Lin, Email: ericlin09@gmail.com
曾任職台灣某遊戲公司研發Game Engine,為書籍“OGRE 入門指南”的譯者之一,專攻Rendering技術與遊戲開發
作者:Bric Lin, Email: ericlin09@gmail.com
曾任職台灣某遊戲公司研發Game Engine,為書籍“OGRE 入門指南”的譯者之一,專攻Rendering技術與遊戲開發
沒有留言:
張貼留言