Unity終於在即將到來的4.6版本內集成了所見即所得的UI解決方案(視頻)。事實上從近幾個版本開始,Unity就在爲這套系統作技術擴展,以保證最終能實現較理想的UI系統。本文試圖經過初步的介紹和試用,讓讀者對這套系統有大致的瞭解,以便更進一步評估這套UI系統好很差用,適合用在什麼項目。爲了不坑挖太深,更進一步的試用和評估我將在《用uGUI開發自定義Toggle Slider控件》中進行論述。爲論述方便,下文將這套New UI System簡稱爲uGUI,而且以X-UI指代現有第三方UI插件。 html
(測試只針對Unity 4.6.0 beta 10,正式版可能會有所出入。目前Unity沒提供文檔,本人半桶水,歡迎羣衆在微博或Issues裏吐槽!) git
Rect Transform繼承自Transform,是uGUI相比X-UI最顯著的區別[注1]。當你爲Empty GameObject加入一個UI Component時,Transform會自動轉換爲Rect Transform。Rect Transform儘可能整合了X-UI常見的anchor(相對父物體的錨點), pivot(中點), stretch(拉伸)等屬性。值得一提的是,這裏的anchor是Rect而非Vector2,由於它不只用於偏移,並且用於縮放。點擊Rect Transform上的準心圖標,還能在彈出的Anchor Presets面板中對其進行快速設置。 github
這個面板仍是不夠直觀,咱們能夠把它當作一張表,上面四個圖標用於設置列,左邊四個圖標用於設置行,也能夠直接點擊裏面的16個圖標同時設置行和列。強大的地方是,按住shift時能同時設置pivot,這時能發現控件雖然不動但position已經在改變。若是按住alt,則設置anchor的同時設置position。若是shift和alt同時按住,那麼你就能同時設置anchor, pivot和position。這個操做方式比起X-UI,真的高明不少,對多分辨率適配頗有幫助。 算法
除此以外,Rect Transform還提供了Blueprint和Lock Rect選項,前者用於對旋轉過的元素進行定位,後者聽說明是能在設置anchor時保持位置不變,暫時沒搞明白。 canvas
uGUI能夠直接在Hierarchy面板中上下拖拽來對渲染進行排序(支持程序控制),越上面的UI會越先被渲染,相比X-UI的global depth排序,這樣的拖拽設計很討好用戶。同時在結構上則和ex2D採用的local depth相似,這樣GO只和同級其它GO進行排序,開發組件會很方便。須要注意的是,這裏排序只是相對UI而言,其它3D物體仍是按原先的次序渲染,而且UI老是渲染在3D物體上面。這就致使你不能像用ex2D那樣直接將粒子系統插入到兩個UI之間。 緩存
這種無需填寫depth值的排序方式,容易致使沒有手工作sprite packing的free版用戶遇到draw call增長。由於全部物體的depth都是自動設置的,Unity保證了每一個物體的depth都是惟一的。這時假設你有一個格子控件,每一個控件用到了兩個Sprite,但你並無把Sprite都拼到同一張貼圖上。因而你每複製一個新的格子出來,draw call就會增長2個,由於Unity會以格子爲單位依次繪製。pro用戶因爲有sprite packing機制,不用擔憂這個問題。(這種狀況在ex2D裏,是以默認提供"unordered"的渲染方式來解決的,這也是NGUI的默認作法。在這種狀況下ex2D會優先以相同depth的相同Sprite爲單位繪製,所以不論有多少個格子,draw call都是2個。除非你就是但願以格子爲單位進行渲染[注6],那麼你能夠在ex2D裏設置渲染方式爲"ordered",或者在NGUI裏給每一個格子設置不一樣的depth。 架構
uGUI自帶了以上控件,其中Image用於顯示Sprite,Raw Image用於顯示Texture,Image Mask和Rect Mask用於clipping。全部控件都是MonoBehaviour,能夠直接從Inspector裏拖到其它GameObject上。 框架
uGUI用Image控件顯示圖片,圖片就是一個Sprite,這意味着Pro用戶不用再製做atlas了,相比X-UI是個大進步,Free用戶同樣能夠手動作Packing。Image提供了Simple, Sliced, Tiled, Filled四種效果,和X-UI保持一致。 ide
uGUI裏,Button控件由兩個GameObject組成,一個包含Image, Button等Component,一個包含Text等Component。這樣設計很組件化,惟一的問題是當用戶想修改Button時,容易不當心選中Label或其它實體。 工具
Button Component主要執行Transition和事件兩個操做。
uGUI控件每每只提供一個自帶事件,要響應更多基本事件的話,須要添加Event Trigger組件。Event Trigger包含如下事件:
能夠在Event Trigger中Add多個事件,每一個事件均可以添加多個命令,用法和控件自帶事件一致。
每一個Canvas都有一個Graphic Raycaster,用於獲取用戶選中的uGUI控件。多個Canvas之間經過設置Graphic Raycaster的priority來設置事件響應的前後次序。當Canvas採用World Space或Camera Space時,Graphic Raycaster的Block選項能夠用來設置遮擋目標。
建立uGUI控件後,Unity會同時建立一個[注4]叫EventSystem的GameObject,用於控制各種事件。能夠看到Unity自帶了兩個Input Module,一個用於響應標準輸入,一個用於響應觸摸操做。Input Module封裝了對Input模塊的調用,根據用戶操做觸發各Event Trigger。理論上咱們能夠編寫本身的Input Module,用來封裝各類外部設備的輸入,只要加入Event System所在的GameObject就行。
Event System組件則統一管理多個Input Module和各類Raycaster。它每一幀調用多個Input Module處理用戶操做,也負責調用多個Raycaster用於獲取用戶點擊的uGUI控件以及2D和3D物體。
2D渲染分兩大類,一類是單純的Sprite繪製,用於渲染場景、角色、粒子等,另外一類是UI繪製。Unity將這兩類需求劃分紅了SpriteRenderer和uGUI兩部分,前者由Transform + SpriteRenderer實現,後者由Rect Transform + CanvasRenderer + UI控件 + Canvas[注2]實現,這樣的兩套相對獨立的機制比起X-UI的UI控件繼承自SpriteRenderer更爲合理。由於在2D遊戲裏SpriteRenderer只須要關心最基本的面片渲染,注重效率,而UI注重各種變換、對齊、操做、動畫,還經常須要Resize VBO。若是SpriteRenderer在設計上須要兼顧UI,就會像X-UI那樣設計得太過複雜,在用戶體驗和性能上都很很差。
這裏咱們探討一下uGUI的渲染機制,當咱們渲染多個使用相同Sprite的控件時,並沒發生dynamic batching,可是drawcall也沒有上升。這就說明Unity在內部使用了專門的一套batching機制,把多個控件的VBO事先合併成了一個。也就是說CanvasRenderer不負責實際渲染,而是由Canvas批量渲染多個CanvasRenderer,這和部分X-UI採用的作法一致。這樣單獨batch的設計有可能使得性能比SpriteRenderer好,也可能致使性能更差。性能會更好的狀況在ex2D裏已經證明了,主要緣由是這樣能更好的平衡CPU和GPU負載,而且能作到更優化的batching算法。性能更差的狀況,在去年舊版的NGUI測試時也遇到了,根本緣由仍是優化不到位致使的(不是貶低,不一樣工具的取捨和麪向市場都不一樣)。而Unity的 SpriteRenderer在手機上的渲染跑分是和ex2D持平的,CanvasRenderer又比SpriteRenderer快[注3],所以uGUI的性能不用擔憂。因爲目前沒有Mac版本,我會在正式版發佈後進行一次手機跑分測試。
uGUI功能完善,操做簡潔,很接地氣。能夠說uGUI是相對X-UI的全面升級,總體架構更爲嚴謹,實現更爲清晰。依託4.5的Module Manager,uGUI以Package的形式提供,也能得到快速的升級[注5]。做爲ex2D v2.0開發者之一,我很看好它未來的發展,uGUI將在大多數場合取代X-UI。
初步感覺: