http://forum.china.unity3d.com/thread-32932-1-1.htmlhtml
劃分畫布緩存
問題:UI Canvas上有一個或多個元素變化時,會污染整個畫布。
畫布(Canvas)是Unity UI的基本組件。它會生成網格來呈現放置在畫布上的UI元素,當UI元素變化時,它會從新生成網格並向GPU發起繪圖調用,從而顯示出UI。
生成這些網格會消耗大量性能。須要將UI元素收集到批處理中,從而儘量減小繪圖調用。由於批處理的生成過程性能消耗較大,一般只在必要時候才從新生成。問題在於,當畫布上有一個或多個元素變化時,必須從新分析整塊畫布,才能獲得繪製元素的最優方法。
許多用戶將整個遊戲的UI都放到一塊畫布,上面擺放了成百上千個元素。所以當修改其中一個元素時,會產生持續數毫秒的CPU使用量飆升狀況。
解決方案:劃分畫布
每塊畫布上的元素都與其它畫布的元素相隔離,因此咱們可使用工具來切分畫布,從而解決Unity UI的批處理問題。
你也能夠經過嵌套畫布來解決,這樣能容許設計師建立大型分層UI,並且沒必要擔憂不一樣內容出如今多個畫布上。子畫布的內容與父畫布和同級畫布相互隔離。它們會保持自帶幾何體,執行本身的批處理。
當使用子畫布分離畫布時,嘗試根據畫布更新時間來分組。例如:分離動態元素和靜態元素。工具
Graphic Raycaster的最佳用法佈局
問題:Graphic Raycaster有哪些最佳用法?
Graphic Raycaster組件可以將輸入內容轉換爲UI事件,它會把觸屏輸入轉爲事件,而後發送給相關UI元素。每一個接收輸入內容的畫布都須要Graphic Raycaster組件,包括子畫布。
儘管該組件名爲Graphic Raycaster,但它卻不是個光線投射器,默認狀況下它只會測試UI圖形。該組件會獲取特定畫布上輸入信息相關的UI元素集,而後執行交點測試,它會針對Graphic Raycaster的畫布上每一個交互式UI元素的RectTransform,檢查輸入事件發生的位置。
解決方案:關閉靜態或非交互式元素的Raycast Target。
例如:有個帶文字的按鈕,關閉該元素的Raycast Target會直接減小Graphic Raycaster每幀進行的交點測試次數。性能
問題:有時候Graphic Raycaster會充當光線投射器使用。
若是將畫布上的渲染模式設爲世界空間攝像機(Worldspace Camera)或屏幕空間攝像機(Screen Space Camera),此時能夠設置阻擋遮罩(Blocking Mask)。
阻擋遮罩決定光線投射器是經過2D物理仍是3D物理投射光線,從而瞭解特定物理對象是否阻擋用戶與UI交互。
解決方案:經過2D或3D物理投射光線會消耗很多性能,因此要謹慎使用該功能。
儘可能減小Graphic Raycaster的數量,不要將Graphic Raycaster添加到非交互式UI畫布上,由於這樣作沒法檢查交互事件。測試
避免使用Camera.main動畫
問題:世界空間畫布須要瞭解交互事件來自哪一個攝像機。
當設置畫布進行渲染時,無論該畫布是在世界空間仍是攝像機的屏幕空間,均可以指定用於爲UI中Graphic Raycaster生成交互事件的攝像機。渲染模式爲「Screen Space - Camera」的畫布須要使用該設置,該設置名爲「Render Camera」。spa
然而在渲染模式爲「World Space」的畫布上,該設置是可選的,名爲「Event Camera」。插件
若是將世界空間畫布的Event Camera字段留空,這不意味着該畫布不會接收事件。它會使用遊戲的主攝像機。爲了肯定哪一個攝像機是主攝像機,該畫布會訪問Camera.main屬性。設計
根據Unity所使用的代碼路徑,每幀中每有一個Graphic Raycaster和世界空間畫布,該畫布會訪問7到10次Camera.main。每次訪問Camera.main都會調用Object.FindObjectWithTag。這個作法在運行時並不合適。
解決方案:避免使用Camera.main
緩存攝像機的引用,而後建立系統來跟蹤主攝像機。若是使用世界空間畫布,要指定Event Camera,不要將該屬性留空。若是須要修改Event Camera,編寫代碼來更新Event Camera屬性。
避免使用佈局分組
問題:每一個影響佈局的UI元素都會至少執行一次GetComponents調用。
當修改佈局系統的一個或多個子元素時,會使佈局變髒。修改後的子元素會使擁有該元素的佈局系統(Layout System)無效化。
簡單介紹一下佈局系統:佈局系統是一組連續的佈局分組(Layout Group),它們在佈局元素(Layout Element)之上。佈局元素不僅是名爲Layout Element的組件,它們還包括UI圖像、文字和Scroll Rect組件,並且Scroll Rect同時也是佈局分組。
回到問題自己,每一個使佈局變髒的UI元素都會至少執行一次GetComponents調用,該調用會在佈局元素父對象上尋找有效的佈局分組。找到有效佈局分組後,它會繼續遍歷Transform層級,直到中止尋找分組或是到達層級的根部分,不管先知足哪一個條件都會中止尋找過程。所以。每一個佈局分組會給每一個子佈局元素的改變過程添加一次GetComponents調用,使嵌套佈局分組的性能變差。
解決方案:避免使用佈局分組。
使用錨點進行比例佈局。在擁有動態元素數量的活躍UI上,考慮編寫代碼來計算佈局,僅在須要時運行該代碼,而不是每次發生改變的時候。
巧妙地彙集UI對象
問題:用錯誤的方法彙集UI對象。
一般狀況下,用戶經過重置父對象來彙集UI對象,而後再禁用對象,但這樣會形成沒必要要的污染。
解決方案:首先禁用對象,而後將其父對象重置爲對象池。
這樣操做僅會改變一次原有的層級,但在重置父對象時,要避免二次改變原有的父對象,也不要改變新的層級。若是要從對象池移除對象,首先重置它的父對象,而後更新數據,再啓用該對象。
UI元素上Animator的最佳用法
問題:如何在UI上使用Animator?
Animator每幀都會改變元素,即便動畫中的數值沒有變化。Animator沒有空指令檢查。
解決方案:
只在頻繁變化的動態元素上加入Animator。對於不多變化的元素,或是僅響應事件時才變化的元素,請自行編寫代碼或補間系統,你能夠在Asset Store資源商店找到許多補間系統插件。
抗鋸齒
問題:UI抗鋸齒不起效
Canvas的Render Mode設置爲Screen Space - Overlay的時候,UI的渲染不會通過MASS buffer,而是直接寫入到Final buffer。
解決方案:
使用Screen Space - Camera模式。