垃圾回收
是什么? | 垃圾回收(Garbage Collection)GC |
工作機制 | 1、Unity 為用戶生成的代碼和腳本采用了自動內存管理。 2、小塊數據(如值類型的局部變量)分配在棧上。大塊數據和長期存儲分配在托管堆上。 3、垃圾收集器 (GC)會定期識別并釋放未使用的堆內存。雖然這是自動運行的,但檢查堆中所有對象的過程可能導致游戲卡頓或運行緩慢。 |
要注意某些不必要的堆分配,這可能會導致?GC?尖峰 :?
1、在?C#?中,字符串是引用類型,而不是值類型。減少不必要的字符串創建或操作。如果需要在運行時構建字符串,請使用StringBuilder類。
2、緩存數組引用,不要在循環中分配數組。
3、使用 GameObject.CompareTag?而不是手動將字符串與?GameObject.tag?進行比較?(返回新字符串會產生垃圾)。?
4、雖然?yield?不會產生垃圾,但創建新的?WaitForSeconds?對象會。緩存并用?WaitForSeconds?對象,而不要在?yield?行中創建它。
using System.Collections;
using UnityEngine;public class Test : MonoBehaviour
{public WaitForSeconds logic;private void Start(){logic = new WaitForSeconds(3);}IEnumerator Check(){yield return logic;Debug.Log("打印");}
}
5、LINQ?和正則表達式 :它們幕后都會進行裝箱,從而產生垃圾。如果性能很重要,請避免使用?LINQ?和正則表達式。
6、如有可能,可以使用?System.GC.Collect?主動觸發垃圾收集。
UI優化
1、避免使用過多層級
拆分層級!在層級視圖中如果游戲對象不需要嵌套,請簡化父子化。較少的層級關系將受益于多線程刷新場景中的變換 (Transform)。復雜層級關系會發生不必要的變換 (Transform) 計算以及更多垃圾收集開銷。
2、不勾選Raycast Target
對與不需要Raycast Target的UI,建議將其禁用。這些小的更改可以減少不必要的計算。
美術資源優化
正確導入紋理
紋理會占用大部分內存,因此,導入設置非常重要。通常,請遵循以下指導原則 :
-
減小 Max Size :使用能生成視覺上可接受的結果的最低設置。這種非破壞性方式,可以快速降低紋理內存。
-
使用 2 的冪 (POT) :Unity 要求移動端紋理壓縮格式 (PVRCT 或 ETC)采用 POT 紋理尺寸。
-
制作紋理圖集 :將多個紋理放置到單個紋理中,可以減少繪制調用和加快渲染速度。使用Unity 精靈圖集 或第三方 Texture Packer 可以制作紋理圖集。
-
關閉 Read/Write Enabled 選項 :如果啟用,此選項在 CPU 和 GPU 可尋址內存中都會創建副本,紋理會占用雙倍內存。大多數情況下,應保持此選項為禁用狀態。如果要在運行時生成紋理,請通過 Texture2D.Apply 強制執行,并且傳入設置為 true 的 makeNoLongerReadable。
-
禁用不必要的 Mip Map :對于在屏幕上大小保持不變的紋理(如 2D 精靈和 UI 圖形),Mip Map 不是必需的,對于與攝像機的距離會變化的 3D 模型,請保留 Mip Map為啟用狀態。
檢查多邊形數量
分辨率越高的模型,需要的內存使用量越大,并且可能占用更長的 GPU 時間。您的背景幾何體是否需要五十萬個多邊形?考慮減少所選 DCC 包中的模型。刪除攝像機的視角看不到的多邊形。使用紋理和法線貼圖而不是高密度網格來實現精細的細節。
優化技術或操作
LOD技術
是什么? | 多層次細節(Level Of Detail ) |
作用 | 根據相機距離物體的遠近來顯示不同精度的模型 |
優點 | 減少場景中模型繪制的面數,提高渲染的性能 |
缺點 | 需要準備多套不同精度的美術資源,同時也增大了游戲體積 |
對象池技術
是什么? | 在開始時初始化若干對象,將它們存到對象池中。需要使用的時候從對象池中取出,使用完后重新放回對象池中。 |
優點 | 可以避免頻繁創建和銷毀對象帶來性能消耗。 |
適用場景 | 如果需要對某種對象進行頻繁創建和銷毀時,例如應用在子彈、敵人等 |
批處理技術?
Unity的批處理(Batching)技術是優化渲染性能的重要手段,它通過減少Draw Call次數來提高渲染效率。
光照烘焙
光照烘焙是Unity中重要的光照優化技術,它通過預計算場景中的光照信息,將結果"烘焙"到光照貼圖(Lightmap)中,從而減少實時計算開銷。
遮擋剔除
(occlusion culling)
遮擋剔除是Unity中一項重要的渲染優化技術,它通過剔除被其他物體完全遮擋的物體來減少不必要的渲染計算。
限制后期處理效果
全屏幕后期效果處理(如發光)會極大降低性能。請在游戲的美術設計中謹慎使用這些效果。
避免過多使用 Animator
Animator 主要用于人形角色,但也常用于動畫化單個值(如 UI 元素的 Alpha 通道)。
避免過多使用Animator,尤其在處理UI動畫時。盡可能對移動設備使用舊版 Animation 組件。
考慮創建補間函數或者使用第三方庫來實現簡單動畫(如 DOTween)。
選擇正確的幀率
1、移動端項目必須在幀率和電池續航時間以及熱節流之間獲得平衡。不需要將設備限值推向 60 fps,可以折衷以 30 fps 運行。Unity 默認移動端為 30 fps。
2、也可以通過 Application.targetFrameRate 在運行時動態調整幀率。例如,甚至可以將緩慢或相對靜止的場景降至 30 fps 以下,而將玩游戲時的 fps 設置保留為較高值。
代碼優化
1、如果確實需要使用 Update,可以考慮每 n 幀運行一次代碼。這是一種應用時間切片 (將繁重的工作負載分布到多個幀的常用技術)的方法。在下面的示例中,我們每三幀運行一次 邏輯
private int interval = 3;void Update()
{if (Time.frameCount % interval == 0){//運行邏輯}
}
2、避免空Unity 事件
即使是空的 MonoBehaviour 也需要資源,因此應刪除空的 Update 或 LateUpdate 方法。
3、刪除調試日志語句Debug.Log
日志語句(尤其是在 Update、LateUpdate 或 FixedUpdate 中)可能會降低性能。在進行構建之前,請禁用日志語句。
4、緩存游戲對象和組件
GameObject.Find、GameObject.GetComponent 和 Camera.main( 在 2020.2之前的版本中)可能開銷較大,應避免在 Update 方法中調用它們。而應在 Start 中調用它們,并且緩存相應結果。