上回說到UIWidget的depth控制了UIDrawCall的層級關(guān)系,因為大家都是用的同一個sortingLayer跟sortingOrder嘛乡话。但是有個問題咯摧玫,看代碼
上一篇文章中我們之說了影響UIWidget的真正順序的其實是每一個drawcall。每個panel保存著其子UIWidget的所有DrawCall绑青,那么诬像,這些drawcall是如何排序的呢。且看上圖闸婴,我們可以忽略sortingLayer跟sortingOrder坏挠,因為正常情況下我們并不會用到,除非我們在panel的Inspector面板勾選了sortingOrder掠拳。
我們知道癞揉,Unity中控制層級的因素有三個,分別是SortingLayer溺欧,SortingOrder跟RenderQueue喊熟。 那么影響drawcall的就只剩下RenderQueue了。
而上圖所見也是如此姐刁,drawcall的renderqueue直接使用了panel的startRenderqueue + i芥牌,也就是說,drawcall列表中聂使,角標(biāo)從小到大壁拉,其對應(yīng)的renderqueue也是逐漸變大,其層級也就是越在前面柏靶,那么這個drawcall所包含的uiwidget就顯示在越前面弃理。
那么我們再看StartRenderQueue的賦值
遍歷所有的Panel,然后以3000為起點屎蜓,第一個panel的startingRenderQueue的值為3000 加上自己所屬的drawcall個數(shù)痘昌,第二個則為3000加上第一個的drawcall個數(shù)再加上第二個的drawcall個數(shù),剩下的以此類推炬转。
這也導(dǎo)致了每個panel下面的drawcall的renderqueue都沒有重復(fù)辆苔,也就不會出現(xiàn)兩個panel中的UISprite交叉顯示的情況。這正是UIPanel能正確分割的原因扼劈。
那么UIPanel的depth在這其中又扮演了什么角色驻啤?我們且看UIPanel的depth
可以看到只有depth一變化,就會重新排序存儲Panel的List荐吵,這樣在LateUpdate中又會走到上面圖片我們看到刷新所有UIPanel的startingRenderQueue骑冗,進(jìn)而刷新所有drawcall的renderQueue赊瞬,這樣一來,就成功的使depth變化的UIPanel的子drawcall的RenderQueue變化沐旨,使之層級變化森逮。這就是我們看到改變了UIPanel的depth,整個UIPanel下方的UIWidget都變化的原因磁携。
那如果兩個Panel的depth一樣褒侧,怎么顯示呢?可以看list的排序方式
如果兩個UIPanel的depth相等谊迄,那么就取他們的InstanceID進(jìn)行比較闷供。
除了這個功能,UIPanel的depth還有幾個地方需要注意统诺,這個雖然不常見歪脏,但是有時候就會被搞得莫名其妙
上圖是UIWidget中的一個字段,用來做UIWidget的碰撞檢測使用粮呢,那么久很清楚了婿失,UIWidget的碰撞先后是跟depth有關(guān)的,但是這個值是有上限的啄寡,也就是1000豪硅。也就是說,相鄰的兩個depth的panel挺物,只要你將低的一方中的一個UIWIdget的depth改為加上一千以后懒浮,它雖然不顯示,但是他是很可能會被點擊到的识藤,攔都攔不住砚著。
上圖顯示的CalculateRaycastDepth返回的就是widget的raycastDepth,而下方直接排序痴昧,取了列表的第一個作為碰撞到的物體稽穆,簡單粗暴是不是。赶撰。舌镶。
還有一個需要注意的是這個
如果UI的alpha為0,它以及其下方的所有子節(jié)點的UI都是無法點擊到的?勰摇:跽邸绒疗!
以上就是NGUI的depth的終極秘密啦G中!吓蘑!
感謝各位看官惕虑,如有不足坟冲,歡迎補(bǔ)充!@D琛健提!
以下是上兩篇基礎(chǔ)
http://www.reibang.com/p/4cfbbd76bfe8? ? 《depth解析上篇》
http://www.reibang.com/p/7a033810706f? 《RenderQueue、SortingOrder伟叛、SortingLayer關(guān)系解析》