關(guān)于NGUI的depth的深度解析<一>

????????用過NGU的兄弟知道砰苍,NGUI是以一個(gè)depth的參數(shù)控制各個(gè)Rect的前后關(guān)系的垃喊。包括UISprite跟UILabel這些繼承是UIWidget的組件,當(dāng)然也包括UIWidget本身奖蔓,UIPanel也有depth猩谊,但是UIPanel的depth跟UIWidget的是一樣的嗎?UIPanel是調(diào)整整個(gè)Panel與Panel之間的層級(jí)關(guān)系糙麦。而UIRect的depth是調(diào)整UIWidget之間的層級(jí)關(guān)系辛孵,雖然聽起來差不多,但是感覺有點(diǎn)小區(qū)別呢赡磅。本篇暫定只解析UIWidget的depth魄缚。 那么UIRect的depth是如何影響UI的先后層級(jí)關(guān)系的呢?

? ? ? ? 首先我們看UIRect的depth代碼焚廊,

depth—set

這里要說一下UIPanel在這其中的作用冶匹,可以看到UIWidget的depth改變以后,之間調(diào)用了UIPanel的RemoveWidget跟AddWidget方法咆瘟,重新將這個(gè)UIWidget進(jìn)行一次刪插操作嚼隘。而這個(gè)刪除跟插入操作不是一般的刪除跟插入,還順帶做了一大堆的事情袒餐。

首先我們看看刪除都做了什么飞蛹,

RemoveWidget

看上去好像只是在如果這個(gè)wiget的pepth為drawcall的開始或者結(jié)束值相等的時(shí)候,將mRebuild賦值為true灸眼∥蚤埽看起來好像沒有做什么對(duì)不對(duì),但是我們?cè)倏催@個(gè)mRebuild做了什么焰宣。

lateupdate

咋一看霉囚,好像也沒做什么呀,只是調(diào)用了一個(gè)叫UIPanel中的FillAllDrawCall的方法而已宛徊。且看

FillAllDrawCall

需要注意的是佛嬉,F(xiàn)illAllDrawCall是在UIPanel的LateUpdate中調(diào)用的,LateUpdate遍歷了所有的UIPanel闸天,當(dāng)每個(gè)panel的mRebuild為ture時(shí)暖呕,這個(gè)penel就調(diào)用自身的FillAllDrawCall方法。由于無法截圖更長苞氮,忽略了上面的一些代碼湾揽,只截了這段創(chuàng)建DrawCall的代碼。那么,這FillAllDrawCall里面做了什么库物,那 這個(gè)DrawCall到底是個(gè)什么東西呢霸旗,我們根據(jù)上面的這個(gè)截圖可以看出來,每個(gè)UIWidget都保存了一個(gè)自身引用的UIDrawCall戚揭,當(dāng)下一個(gè)UIWidget的所屬的材質(zhì)诱告、貼圖、Shader有一者不一樣民晒,則重新創(chuàng)建一個(gè)drawcall精居,否則刷新這個(gè)drawcall的開始depth跟結(jié)尾的depth。這個(gè)刷新方式潜必,導(dǎo)致我們?cè)趧?chuàng)建UI界面的使用靴姿,也需要有些注意事項(xiàng),這個(gè)后面再說磁滚。

而depth的作用就在這里了佛吓,由此可見,UIRect的層級(jí)關(guān)系是跟UIDrawCall這個(gè)東西有關(guān)的垂攘。那么UIDrawCall又是個(gè)什么玩意呢维雇?我們不是在研究depth嘛,怎么牽扯到UIDrawCall上面了晒他,別急谆沃,且跟我慢慢分析。


FillAllDrwaCall
FillAllDrawCall

這兩段代碼緊跟著我們上面的DrawCall.Create()的地方仪芒,大概就是前后關(guān)系,在UIWidget的WriteBuBuffers中會(huì)將Wigiget的頂點(diǎn)(verts)耕陷,UV掂名,顏色等從UIGeonetry中寫入到所屬的drawCall中去,然后再DrawCall中的UpdateGeometry中進(jìn)行修改刷新渲染哟沫。也就是說饺蔑,最終的我的UI的效果跟層級(jí)表現(xiàn)是根據(jù)DrawCall的渲染表現(xiàn)來呈現(xiàn)的,那drawcall之間的層級(jí)關(guān)系又是如何確定的呢嗜诀。且看

RebuildMaterial

前面說到了最后調(diào)用了UIDrawCall的UpGeometry猾警,在這個(gè)方法里面我們可以發(fā)現(xiàn),它在賦值了drawcall的Mesh的頂點(diǎn)跟UV一系列的賦值操作以后隆敢,將mesh賦值給了自己的MeshFiter(沒錯(cuò)发皿,就是用MeshFilter),然后調(diào)用了上圖的這個(gè)ReBuildMaterial方法拂蝎,將drawCall的sortingLayer跟sotringOrder賦值給了render穴墅。由此真相大白,原來UISprite的背后是用DrawCall渲染的,而DrawCall是用mesh渲染的玄货,層級(jí)的最終還是走的Unigy的Sortinglayer跟SortingOrder皇钞。

那么UIDrawCall的sortingLayer跟SortingOrder又是在哪里賦值的呢,我們之前說了松捉,F(xiàn)illAllDrawCall是在Panel的LateUpdate方法中的夹界。追根朔源我們可以發(fā)現(xiàn),在LateUpdate中還有一個(gè)方法隘世,

LateUpdate

可以看到可柿,有個(gè)UpdateDrawCalls的方法根據(jù)UIPanel的設(shè)置不同而被調(diào)用。而正式這個(gè)方法以舒,遍歷了每個(gè)UIDrawCall并對(duì)其SortingLayer跟SortingOrder進(jìn)行了賦值操作

UpdateDrawCalls

這里對(duì)每個(gè)UIDrawCall的RenderQueue趾痘,SortingLayer,SortgingOrder進(jìn)行了賦值

需要注意的是蔓钟,這里的SotringLayer屬性永票,如果useSortingOrder為false的話,他是被設(shè)置為null的

UsedSortingOrder

看引用可知滥沫,它就是UIPanel的Inspector面板上面的SotringOrder的toggle侣集,如果被勾選,則上面的SortingLayer生效兰绣,否則世分,無論你將SortingLayer改成什么,它都是會(huì)設(shè)置為Null缀辩,而設(shè)置為null的話臭埋,系統(tǒng)會(huì)自動(dòng)設(shè)置為第一層的SortingLayer,默認(rèn)是Default臀玄,但是也不一定瓢阴,如果你在Default前面又新建了其他比如Base層,那么它就會(huì)默認(rèn)設(shè)置成Base層健无,因?yàn)楝F(xiàn)在Base層已經(jīng)是第一層了荣恐。

文章開始時(shí)我們也說過,關(guān)于UIDrawCall機(jī)制導(dǎo)致我們創(chuàng)建UI的時(shí)候需要注意一些事情累贤〉拢回頭看UIDrwaCall的地方,我們可以發(fā)現(xiàn)由于遍歷UIWiget的list進(jìn)行創(chuàng)建drawcall臼膏,一旦上一個(gè)的材質(zhì)硼被,shader或者貼圖有一者不同,那么它就會(huì)重新創(chuàng)建一個(gè)新的drawcall來保存當(dāng)前widget的渲染內(nèi)容渗磅,這樣一來祷嘶,如果我們創(chuàng)建UI的時(shí)候屎媳,一不注意,就會(huì)導(dǎo)致drawcall數(shù)量激增论巍。激增會(huì)有什么后果呢烛谊,最直觀的反應(yīng)就在性能上,很可能導(dǎo)致我們的游戲卡頓嘉汰,浪費(fèi)大量內(nèi)存在渲染UI上面丹禀。

那么如何避免呢,我們可以盡量保持同一個(gè)圖集的Sprite在順序的depth上面鞋怀,這樣就會(huì)將他們都放在同一個(gè)DrawCall中進(jìn)行渲染双泪。當(dāng)然,也沒有必要斤斤計(jì)較密似,因?yàn)榇罱║I真的很累焙矛,手都能點(diǎn)到抽搐~_~。

搭建UI的時(shí)候残腌,可以考慮depth分層機(jī)制村斟,比如[0,20]是屬于背景的,比如[21,40]是屬于文字的抛猫,文字的depth盡量跟Sprite分開蟆盹,因?yàn)槲覀兺ǔV皇褂靡粌蓚€(gè)文字,而且文字都在Sprite前面闺金,能放一起當(dāng)然最好不過逾滥。當(dāng)然只是個(gè)參考,不建議加一個(gè)UI就加一層depth败匹,這樣要插入一個(gè)就很麻煩寨昙,層級(jí)很容易錯(cuò)亂。

可以看到我們的Panel下面有個(gè)Show Draw Call的按鈕掀亩,點(diǎn)擊就會(huì)看到

DrawCallTool

這是當(dāng)前Panel中所有的DrawCall毅待,可以看到我們場景中總共有兩個(gè)DrawCall,這個(gè)panel占了一個(gè)归榕。很清晰易懂,材質(zhì)吱涉,以及包含哪些Widgets刹泄,RederQueue跟三角面數(shù)都貼出來了。Widgets可以看到我們這個(gè)DrawCall中包含了多少Widget元素怎爵,也就是包含多少UISprite跟UIlabel這些繼承子UIWidget的組件特石,而drawCall的個(gè)數(shù)很很清晰,我們創(chuàng)建的時(shí)候鳖链,可以根據(jù)這個(gè)面板進(jìn)行調(diào)整優(yōu)化姆蘸。

另外如果對(duì)Unity的SortingLayer墩莫,RenderQueue跟SortingOrder不熟的同學(xué),可以查看我的上一篇文章哦逞敷!

地址:http://www.reibang.com/p/7a033810706f? ??<論RenderQueue狂秦、SortingLayer、SortingOrder關(guān)系>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末推捐,一起剝皮案震驚了整個(gè)濱河市裂问,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌牛柒,老刑警劉巖堪簿,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異皮壁,居然都是意外死亡椭更,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蛾魄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來虑瀑,“玉大人,你說我怎么就攤上這事畏腕〗纱ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵描馅,是天一觀的道長把夸。 經(jīng)常有香客問我,道長铭污,這世上最難降的妖魔是什么恋日? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮嘹狞,結(jié)果婚禮上岂膳,老公的妹妹穿的比我還像新娘。我一直安慰自己磅网,他們只是感情好谈截,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著涧偷,像睡著了一般簸喂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上燎潮,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天喻鳄,我揣著相機(jī)與錄音,去河邊找鬼确封。 笑死除呵,一個(gè)胖子當(dāng)著我的面吹牛再菊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播颜曾,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼纠拔,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了泛啸?” 一聲冷哼從身側(cè)響起绿语,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎候址,沒想到半個(gè)月后吕粹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岗仑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年匹耕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荠雕。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡稳其,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出炸卑,到底是詐尸還是另有隱情既鞠,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布盖文,位于F島的核電站嘱蛋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏五续。R本人自食惡果不足惜洒敏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疙驾。 院中可真熱鬧凶伙,春花似錦、人聲如沸它碎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扳肛。三九已至傻挂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間敞峭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工蝉仇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旋讹,地道東北人殖蚕。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像沉迹,于是被迫代替她去往敵國和親睦疫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 目錄 1、介紹兩大UI插件NGUI和UGUI2葫松、unity渲染順序控制方式3瓦糕、NGUI的控制4、UGUI的控制5腋么、...
    小飛不會(huì)飛_閱讀 7,153評(píng)論 4 13
  • 轉(zhuǎn)自:https://blog.csdn.net/dingxiaowei2013/article/details/...
    豆錚閱讀 1,259評(píng)論 0 2
  • 以下內(nèi)容基于 NGUI v.3.11.2 咕娄。示例是在 Unity 5.5 中測試。 渲染結(jié)構(gòu) NGUI 用 Pan...
    YLME閱讀 1,885評(píng)論 0 1
  • 一:什么是協(xié)同程序珊擂?答:在主線程運(yùn)行時(shí)同時(shí)開啟另一段邏輯處理圣勒,來協(xié)助當(dāng)前程序的執(zhí)行。換句話說摧扇,開啟協(xié)程就是開啟一個(gè)...
    CrixalisAs閱讀 2,076評(píng)論 1 7
  • 一:什么是協(xié)同程序圣贸? 答:在主線程運(yùn)行時(shí)同時(shí)開啟另一段邏輯處理,來協(xié)助當(dāng)前程序的執(zhí)行扛稽。換句話說吁峻,開啟協(xié)程就是開啟一...
    好怕怕閱讀 3,886評(píng)論 2 23