Unity性能優化之代碼優化小技巧
本文參與「Unity性能優化」有獎徵文活動
對於Unity性能優化,目前接觸到的大概有這幾個方面:
1. Draw Call;
2. 資源(模型、貼圖、粒子);
3. 渲染(相機、光照、Shader);
4. 網路;
5. 代碼(代碼編寫、資源載入、物理系統)。
可以在Unity自帶的Profiler窗口查看項目性能消耗主要在哪幾個地方,然後有針對性的進行優化。
作為一個程序,這裡跟大家分享一下最近常用到代碼方面的一點技巧,如有不足之處,歡迎大大們提出寶貴意見~
1. 在場景中有大量物體頻繁的激活或隱藏時,不使用SetActive(),在需要隱藏時移到屏幕外 ,顯示時再移到屏幕內,即修改transform.position。還有一個方法,把需要隱藏的物體設為一個已隱藏的物體的子物體,因為父物體是未激活狀態,子物體會自動隱藏,不過這種方法消耗與SetActive()差不多,不推薦使用。
下面是測試代碼:
輸出結果:
SetActive(true)消耗最大,SetActive(false)與transform.parent其次,transform.position消耗最小,佔用的時間可以忽略不計。
2. 動態實例化到場景的物體,名字都會有一個後綴(Clone),有時候為了方便識別,會修改其名字,同樣會產生性能消耗。比如:
3. 在不影響正常運行結果的情況下,減少Update或FixUpdate的調用次數
假設現在將所有的Updata刷新邏輯寫在DoUpdata中。
3.1 每隔一定數量幀,執行一次DoUpdata。
3.2 使用協程While(true)循環,每次循環間隔一定時間,調用DoUpdata,需要在Start函數中開啟協程。
3.3 使用InvokeRepeating循環調用DoUpdata。
4. 使用對象池
操作目標相對較少,可簡化對象池,實現效果。
4.1 簡化一
4.2 簡化二
如果目標對象較多,就需要寫一個正經的對象池了。
5. 音效播放時,為避免頻繁創建、銷毀播放器,可以對音效統一管理。
6. 場景中經常需要動態生成GameObject,當一次創建的數量較多時,在不影響使用的情況下,可以使用協程,在多幀內完成創建。
7. 部分簡單的物理計算可以不使用Unity提供的物理系統,簡化物理計算量。
8. 選擇合理的數據結構存儲數據。
9. 其他
9.1 盡量避免在Update和for循環內創建臨時變數。
9.2 盡量避免創建臨時字元串。
9.3 可以使用for循環的情況,就不用foreach。
9.4 每個繼承MonoBehaviour的類,都會自動生成Update方法,但很多類是用不到Update的,這時候需要將其刪除,畢竟實時調用空方法,多少還是有消耗的。
9.5 數值計算中使用乘法而不用觸發,比如 a / 2, 可以寫成 a * 0.5f。
9.6 比較他Tag值時,使用if(gameObject.CompareTag("Tag")),而不是if(gameObject.tag == "Tag")。
9.7 開發過程中會各種Debug,這也會有一定的消耗,可以對Debug進行封裝,設置一個bool值,不過這樣console面板雙擊不會跳轉到調用Debug的代碼行,最好的做法是將其做成dll文件。
關於Unity性能優化中的代碼優化技巧暫時就想到了這麼多,期待大大們補充。

