原文:https://blog.csdn.net/u011926026/article/details/75175087
原文:https://www.jianshu.com/p/061e67308e5f
UGUI的层叠顺序是按照Hierarchy中的顺序从上往下进行的,也就是越靠上的组件,就会被画在越底部。
UGUI渲染顺序的确定有2个步骤:
1:第一步计算每个UI元素的层级号
先从直观的角度来解释计算层级号的算法,如果有一个UI元素,它所占的屏幕范围内(通常是矩形),如果没有任何UI在它的底下,那么它的层级号就是0(最底下);如果有一个UI在其底下且该UI可以和它Batch,那它的层级号与底下的UI层级一样;如果有一个UI在其底下但是无法与它Batch,那它的层级号为底下的UI的层级+1;如果有多个UI都在其下面,那么按前两种方式遍历计算所有的层级号,其中最大的那个作为自己的层级号。
2:第二步合并相同层级号中可以Batch的元素作为一个批次,并对批次进行排序
有了层级号之后,就要合并批次了,此时,Unity会将每一层的所有元素进行一个排序(按照材质、纹理等信息),合并掉可以Batch的元素成为一个批次,目前已知的排序规则是,Text组件会排在Image组件之前渲染,而同一类组件的情况下排序规则未知(好像并没什么规则)。经过以上排序,就可以得到一个有序的批次序列了。这时,Unity会再做一个优化,即如果相邻间的两个批次正好可以Batch的话就会进行Batch。
根据以上规则,就可以得出一些“摆UI”的技巧:
1:有相同材质和纹理的UI元素是可以Batch的,可以Batch的UI上下叠在一块不会影响性能,但是如果不能Batch的UI元素叠在一块,就会增加Drawcall开销。
2:要注意UI元素间的层叠关系,建议用“T”工具查看其矩形大小,因为有些图片透明,但是却叠在其它UI上面了,然后又无法Batch的话,就会无故多许多Drawcall。
3:UI中出现最多的就是Image与Text组件,当Text叠在Image上面(如Button),然后Text上又叠了一个图片时,就会至少多2个Drawcall,可以考虑将字体直接印在下面的图片上。
4:有些情况可以考虑人为增加层级从而减少Drawcall,比如一个Text的层级为0,另一个可Batch的Text叠在一个图片A上,层级为1,那此时2个Text因为层级不同会安排2个Drawcall,但如果在第一个Text下放一个透明的图片(与图片A可Batch),那两个Text的层级就一致了,Drawcall就可以减少一个。
UGUI的DrawCall的形成规则:在合并时只有真正发生了叠加的UI元素会生成新的DrawCall。(如下图)
优化策略
1:查看元素叠加情况(线框图),尽量不要让元素有重叠的情况。
2:Mask组件使用了模版缓存,移动平台需要Use 24-bit Depth Buffer(Tegra GPU 2、3上不支持,4支持)。Mask中的UI元素无法与外界UI元素合批。
3:UI变色:修改材质和修改组件属性两种方式
3.1 合并DrawCall一定要是相同的材质,修改材质会将本来已合并的DrawCall分离开,就导致了DrawCall的增加及Canvas的重建。
3.2 修改组件的属性(Button中Transition中的ColorTint属性)只会修改Canvas中的VBO数据。
4:Screen Space-Camera模式下,一个Canvas中的任何一个UI元素只要在屏幕中,则这个Canvas中的其他UI元素即使在屏幕外DrawCall仍不会减少。