1. 程式人生 > >Unity製作頭頂血條方式對比與優化

Unity製作頭頂血條方式對比與優化

製作方式主要有四種:OnGUI、NGUI、UGUI、Shader

區別

  1. UGUI的Canvas 有世界座標和螢幕座標
  2. UGUI的Image可以使用material
  3. UGUI通過Mask來裁剪,而NGUI通過Panel的Clip
  4. NGUI的渲染前後順序是通過Widget的Depth,而UGUI渲染順序根據Hierarchy的順序,越下面渲染在頂層.
  5. UGUI 不需要繫結Colliders,UI可以自動攔截事件
  6. UGUI的Anchor是相對父物件,沒有提供高階選項,個人感覺uGUI的Anchor操作起來比NGUI更方便
  7. UGUI沒有Atlas一說,使用Sprite Packer
  8. UGUI的Navgation在Scene中能視覺化
  9. UGUI的事件需要實現事件系統的介面,但寫起來也算簡單
  10. UGUI的Button屬性面板的的OnClick

優劣勢對比

OnGUI
在Unity4.6之前,官方提供的是OnGUI函式來開發UI介面,當然問題也比較多,首先不支援視覺化開發,其次UI始終位於所有3D物件的上方,無法實現在UI上新增3D模型的效果。
現在一般這套系統多用來在Unity編輯器中開發介面或者快速搭建一些除錯介面時使用。

Shader
對於不同螢幕比例糾結時,用shader畫好點。網上只看到用來製作簡單血條,具體對比尚不清楚。

比較主流的是用NGUI和UGUI,先貼出部分對比圖
這裡寫圖片描述

優點:

  1. 首先,5.2版本之後,Unity逐漸將一部分UGUI的計算放到子執行緒去做,以此來緩解主執行緒的壓力;
  2. 其次,UGUI的UIMesh生成是通過底層C++程式碼實現的,而NGUI只能通過在上層不斷建立vertex list來進行,這樣在堆記憶體的管理上,UGUI確實要好很多,帶來的隱性收益就是GC觸發次數會少很多。
  3. NGUI還保留著圖集,需要進行圖集的維護。而UGUI沒有圖集的概念,可以充分利用資源,避免重複資源。
  4. UGUI出現了錨點的概念,更方便螢幕自適應。
  5. UGUI尚未成熟,但畢竟是官方的,新出的unity5使用了全新的ab打包方式,看上去要封殺ngui的樣子。

缺點:

  1. 不能很視覺化的製作 draggable object
  2. 暫時沒有 localization(本地化)支援
  3. scroll view只有Panel,沒有camera scroll view
  4. 沒有 UIWrap 來 迴圈 scrollview 內容
  5. 暫時沒有Tween元件及Play Audio,Button Offset,需要DoTween之類外掛輔助
  6. UGUI沒有 UIWrap 來迴圈 scrollview 內容。

NGUI
大名鼎鼎的NGUI是可以看做是開發Unity遊戲必備的外掛,支援視覺化開發,同時也支援2D和3D UI的開發,想在UI上顯示3D模型和粒子也沒問題。一套NGUI的學習筆記:http://www.cnblogs.com/hammerc/p/4481597.html

優點:

  1. NGUI支援圖文混排,UGUI暫未發現支援此功能。
  2. ngui是外部開發的外掛,但是ngui比ugui早很多

UGUI注意點:

  1. 要防止多個canvas疊加點選穿透,canvas裡面的graphics raycaster調整到恰當選項
  2. 防止canvas在物體上層,點選canvas卻穿透到物體上,觸發物體的點選的事件,請參見下面示例程式碼

NGUI注意點:(超級影響效能的幾點)

  1. 動畫最好作用於panel而不是sprite
  2. Sprite Type中的tile能不用就不用,卡死人

個人決定用UGUI,以為為記錄的注意事項

  1. 一般會把slider下面的Background和Handle Slide Area刪除掉或者禁用掉。
  2. 要實現任務跟隨,必須把Canvas的渲染模式選擇WorldSpace,然後把相機新增進去,這是最重要最關鍵的一步。
  3. 在Player身上加一個Follow指令碼,在Player身上加指令碼而不在slider身上加指令碼的原因是我想讓血條超出螢幕就關閉顯示,這樣對優化有好處。
  4. 給每個物體下掛一個canvas,便於管理,但是會每個canvas會產生一條DrawCall??

UGUI效能優化

UGUI會自動檢測優化,如果多個材質間沒有遮擋或只有小部分不影響的遮擋則會合並DrawCall為一個。如下圖:
這裡寫圖片描述

  • 儘可能保證Text在Image的上方。字型的DrawCall就可能自動會優化,而不需要像NGUI那樣讓字型跟圖片pack在一起來減少DrawCall。
  • 儘可能保證Image之間不存在不必要的重疊。

UI變色:修改材質和修改頂點色兩種方式

  1. 合併DrawCall一定要是相同的材質,修改材質會將本來已合併的DrawCall分離開,就導致了DrawCall的增加及Canvas的重建。
  2. 修改頂點色(Button中Transition中的ColorTint方式)只會修改Canvas中的資料。

UI邊框:Sliced & Fill Center

  1. Sliced模式的Sprite更節省紋理尺寸。
  2. 中空的邊框不應該勾選Fill Center,可減小Fill rate。

Mask的代價,通過Stencil buffer實現

  1. 移動平臺需要Use 24-bit Depth Buffer(Tegra GPU 2、3上不支援,4支援)。
  2. Mask中的UI元素無法與其他batch,從而增加DrawCall。
  3. 可以的話嘗試用Filled Sprite代替。

動畫:Text vs Image

  1. 如果Image上做了動畫則Canvas需要重建,Image的頂點數一般不會很多,開銷不會很大。
  2. Text與文字內容(生成的網格數)相關,如果文字比較多則相比Image開銷可能會翻倍。

Canvas的重建主要就是為了合併DrawCall,可以將有動畫的文字放在單獨的Canvas中去,手動分離DrawCall(增加DrawCall)後就不會再要去跟別的文字作合併,該Canvas就不需要再重建故減少了重建開銷。

儘可能使用緩衝池。如人物身上的傷害數字,生成時會有較大的開銷因為有Mesh的生成等過程。