https://unity3d.com/cn/learn/tutorials/topics/best-practices/fundamentals-unity-ui?playlist=30089

理解組成Unity UI系統(tǒng)的各個(gè)部分很重要。一些基礎(chǔ)的類和組件一起組成了這個(gè)系統(tǒng)。這一章節(jié)介紹一些的這系列文章所用到的術(shù)語,然后討論一些Unity UI 關(guān)鍵系統(tǒng)的底層行為。

術(shù)語

Canvas是Unity的一個(gè)內(nèi)部組件(native-code Unity Component)。由Unity渲染系統(tǒng)使用,可以提供將在游戲世界空間中繪制的分層幾何圖形。

Canvas負(fù)責(zé)把它們上面幾何體合并成批次,生成合適的渲染指令,發(fā)送給Unity的圖像系統(tǒng)。所有這些都是Unity 本地C++代碼實(shí)現(xiàn)的,被稱作rebatch 或者 batch build。當(dāng)一個(gè)Canvas被標(biāo)記為包含需要被rebatch的幾何圖形,那這個(gè)Canvas被認(rèn)為dirty。

幾何圖形通過 Canvas Render 組件傳遞給Canvas。

一個(gè) Sub-canvas 是一個(gè)嵌套在另一個(gè)Canvas下的Canvas。Sub-canvas 是它的子級(jí)和它們的父級(jí)隔離:一個(gè)dirty的子級(jí)不會(huì)強(qiáng)制它的父級(jí)去重新生成幾何圖形,反之亦然。(一個(gè)canvas是一個(gè)重繪單位)[1]

Graphic是Unity UI庫(kù)提供的基類。它是所有能為Canvas系統(tǒng)提供可繪制幾何圖形的Unity UI C# 類的基類(Image,RawImage,Text)。大部分內(nèi)置的Unity UI圖形都是 MaskableGraphic的子類,這樣它們可以通過IMaskable接口來實(shí)現(xiàn)遮罩。主要的可繪制的子類是 Image 和 Text,它們提供了同名的組件。

Layout components 控制RectTransform的大小和位置,通常被用來創(chuàng)建一些復(fù)雜的排版,這些排版依賴于它們內(nèi)容的相對(duì)大小和相對(duì)位置。排版組件只依賴于RectTransform,并且只影響它們管理的RectTransform。它們不依賴圖形類,并且它們可以獨(dú)立于Unity UI圖形組件使用。

圖形組件和排版組件,都依賴于CanvasUpdateRegistry類,這是UnityEditor內(nèi)不可見的接口。這個(gè)類記錄那些需要被更新的排版和圖形組件,并且當(dāng)其關(guān)聯(lián)的Canavs觸發(fā)willRenderCanvases事件時(shí),觸發(fā)更新。

圖形組件和排版組件的更新被稱為重建(rebuild)。重建的過程會(huì)在之后的文檔中詳細(xì)介紹。

渲染細(xì)節(jié)

當(dāng)使用Unity UI 制作用戶界面時(shí),記住,所有的被canvas繪制的圖形都是被放在透明渲染隊(duì)列。這意味著,Unity UI產(chǎn)生的圖形都會(huì)使用透明混合(alpha blending)從后向前渲染。有一個(gè)重要的性能點(diǎn)要注意:圖形上的每一個(gè)像素都會(huì)被采樣,即使它被另一個(gè)不透明的圖形完全覆蓋。在移動(dòng)設(shè)備上,大量的的過度繪制(overdraw)可以快速超出GPU填充率的上限。

合批過程(Canvases)

合批過程是指Canvas合并UI元素的網(wǎng)格,并且生成發(fā)送給Unity渲染管線的命令。這個(gè)過程產(chǎn)生的結(jié)果會(huì)被緩存住,直到他們被重新標(biāo)記為dirty,組成它的任何一個(gè)網(wǎng)格變化都會(huì)使其變?yōu)閐irty。

Canvas使用的網(wǎng)格都是從綁定在Canvas上的CanvasRenderer獲得,但是不包含子Canvas的網(wǎng)格。

計(jì)算合批需要按照網(wǎng)格的深度,是否遮擋,是否共享材質(zhì)等方面排序。這個(gè)操作是多線程的,因此不同的CPU結(jié)構(gòu),它的性能也不同,特別是移動(dòng)SoCs(通常有幾個(gè)CPU核)和臺(tái)式CPU(通常有4個(gè)或更多的核)。

重繪過程(Graphics)

重繪過程是指Unity UI 的C# 圖形組件的排版和網(wǎng)格被重新計(jì)算。這在 CanvasUpdateRegistry類中執(zhí)行。記住這是一個(gè)C#類,并且可以再Unity Bitbucket上找到。

CanvasUpdateRegistry內(nèi)部,需要關(guān)注的方法是PerformUpdate。當(dāng)Canvas組件觸發(fā)WillRenderCanvases事件時(shí)都會(huì)調(diào)用這個(gè)方法。這個(gè)事件每一幀都會(huì)執(zhí)行一次。

PerformUpdate執(zhí)行三個(gè)步驟:

  • 標(biāo)記為dirty的排版組件通過ICanvasElement.Rebuild方法重建布局。

  • 任何注冊(cè)過的裁剪組件(如mask),需要去裁剪所有可剔除的組件。這是通過ClippingRegistry.Cull實(shí)現(xiàn)的。

  • 被標(biāo)記為dirty的圖形組件,重建它們的圖形元素。

對(duì)于排版和圖形的重建,這些過程都會(huì)分解成過個(gè)部分。排版重建分成三個(gè)過程(PreLayout, Layout and PostLayout),圖形重建包含兩個(gè)過程(PreRender and LatePreRender)。

排版重建

要重新計(jì)算包含一個(gè)或多個(gè)布局組件合適的位置(大?。?,設(shè)置合適的層級(jí)順序很重要。在層級(jí)監(jiān)視器(hierarchy )中排版靠近根節(jié)點(diǎn)的可以能會(huì)影響它子集的排版,所以需要被先計(jì)算。
為了實(shí)現(xiàn)這個(gè),Unity UI 按照hierarchy中深度對(duì)dirty的排版組件排序,越高的(父節(jié)點(diǎn)少的)排在前面。排序后的布局組件被要求重建它們的布局;這就是通過改變布局組件來控制UI元素位置和大小。有關(guān)布局如何影響單個(gè)元素更多詳細(xì)信息,參閱Unity 手冊(cè)中UI Auto Layout部分。

圖形重建

當(dāng)重建UI的時(shí)候,Unity UI 會(huì)調(diào)用ICanvasElement的Rebuild接口。圖形實(shí)現(xiàn)這個(gè)接口,在PreRender階段執(zhí)行兩個(gè)步驟。

  • 如果定點(diǎn)數(shù)據(jù)被標(biāo)記為dirty(如RectTransfom改變大?。?,那么需要重建網(wǎng)格。

  • 如果材質(zhì)數(shù)據(jù)標(biāo)記為dirty(如材質(zhì)或者紋理改變),關(guān)聯(lián)的CanvasRenderer的材質(zhì)也需要被更新。
    圖形重建不是通過按照指定順序設(shè)置圖形組件層級(jí)執(zhí)行的,不需要任何排序操作。

尾注

  1. 有一些說法是不正確的,如改變父物體的畫布,會(huì)導(dǎo)致子物體畫布調(diào)整大小。

http://www.cnblogs.com/chiguozi/p/6770468.html