先列出转载链接:
http://game.ceeger.com/forum/read.php?tid=8917
转载原文:
问题源自一个帖子,因为上传的图比较多,就另开了这个贴写下自己的试验结果,原帖在下面链接中 http://game.ceeger.com/forum/read.php?tid=8911 NGUI中是用depth来控制sprite显示顺序的,本来这很好用,但碰到上面帖子中的问题时却不好解决了,于是我试验了下。以下是一些总结,不对的地方请指正。 下面的内容可能看起来比较绕,这样的话只需实际试验下就能很容易的知道结果,呵呵 如果还是看不明白,可以先看1楼,那里有个总结 1,同一个panel下,同一个atlas的不同sprite的显示只受depth的控制,这是最经常用的方式。此时不论精灵的z轴如何变化,depth高的一定在前面。 比如精灵A的z轴是-10,更靠近相机,但它的depth是0,而精灵B的z轴是0但depth是1,那么精灵B还是显示在前面 如下图,0、1、2的前缀分别是三者的depth值,则三者的排列就是如图的由下到上,2_Label在最上面 现在在depth不变的前提下修改z轴的值。将0_Dark的z轴调为-100,则它离相机更近了,看上去应该挡住后面的两个才对,但Game场景中三者的关系并没有改变,也就是说虽然看上去0_Dark应该挡住后面的东西,但并没有这样,还是depth起作用,也就是feiben同学所说的“相同atlas其实是共用同一个Z轴深度”。 2,不同panel下,同一个atlas的不同sprite不受depth的控制,而受z轴控制。此时只需稍微调节下其中一个精灵的z轴就可以,比如0.1,就可以控制sprite的显示 比如接着1中的图,新建一个panel_B,将1_NGUI拖到里面,会看到它盖住了0和2,现在调节depth不起作用,无论1_NGUI的depth调成多少,都不会改变它在最上面的状态 现在调节下1_NGUI的z轴为0.1,则它到了最后面 而比如现在想把在panel_B中的1_NGUI重新显示在0和2之间,能办到么?经过试验会发现无论怎么调三者的z轴,都不能将NGUI放到0和2之间,因为它们是一个图集中的精灵,共用一个z轴深度 比如将0_Dark的z设为100,此时1_NGUI的z轴还是0.1,但1_NGUI重新跑到了最上面,而不是中间 再把Label的z设为-100,NGUI是被覆盖了,但Dark也跟着跑到了上面,注意此时三者的空间位置,NGUI的确是在中间的,但还是被后面的Dark挡住了 你也许会感觉这是自找麻烦,没事把同一个atlas的精灵放到两个panel中干什么呢?一般情况下是自找麻烦,但为了解决上面帖子中提到的问题,这是个解决的办法,如3 备注:我也重新做了一遍试验,2这种情况跟原文描述的不一样,我的如果两个panel自身的depth值不一样,那么panel大的那个的所有物件会覆盖在另外一个panel,即panel的depth大的物体后画,此时调z轴没有用,如果两个panel值一样,绘制的情况目前我还没有找出规律,但是可以确定的是跟调z轴也没有关系,因为我同一个panel下的两个物体调z轴改变不了覆盖关系,大depth的panel下的物体调z轴后也不能移到小panel的物体后面去,虽然在scene场景中会移动到后面,但运行后没有移动到后面。而且此时depth对物体的显示是有用的,比如同depth的panelA和PanelB,A下面挂了两个Sprite,B下面挂了一个Sprite,三个Sprite来自同一个altas,那么就是谁的Depth大谁就最后绘制。可以这样总结,每个widget的depth是根据 它自身的depth和它所在的Panel的depth位参数算出来的值,并且Panel的depth占了非常大比重。最终它们的绘制顺序还是依据的depth。不知道这跟版本有没有关系,我测试的版本是ngui 3.0。3,不同panel下,不同atlas的精灵的穿插,受z轴的控制。 备注:这个还是有问题,同一个panel下,不同Atlas的sprite还是只跟它们的depth有关系,跟z轴没有关系,同depth的画绘制顺序目前我没有能够找出规律。 5,(修改)对于panel是否会产生drawcall,之前的试验存在误区,当时是直接复制带着sprite的Panel,这的确会产生新的drawcall,这是因为在复制时panel的scale被修改了,由1变成了0.9999304之类的,这会导致drawcall增加了1个,而之后再复制这个由复制产生的panel,scale还是0.9999304,所以drawcall不会再变。 而之所以对panel是否会产生drawcall,是因为官方例7中只用了2个Atlas,但drawcall却是5个,当时简单的认为是panel的问题。 |
ngui官网对Panel的depth的说明,两个Panel最好不要用相同的depth,否则ngui内部会拆分Drawcall来处理这种情况,会比较费。
其实主要的是不知道这种情况下Panel的depth最后是以什么形式加权到下面的widgets的,所以没办法掌控。
All panels have a Depth value which affects all widgets underneath. If you’re creating a complex UI with multiple windows, it’s often best to have one UIPanel per window. The depth value of panels carries a lot more weight than the depth value on individual widgets, so it’s a good idea to ensure that your panels don’t share depth values. If values get shared, draw calls will start to get split up frequently in order to preserve the draw order, resulting in a lot more draw calls than usual.
我自己的测试的结论如下:
每个Widget会根据一个算法公式将自己的depth和它所在的panel的depth合起来计算一个depth,并且它所在的panel的depth会占有非常大的比重,可以认定位panel大的,最后算出来的depth一定大,然后渲染的顺序严格按照最后算出来的depth从小到大排,大的后渲染。depth值一样大的,包括同一个panel下的所有同depth的widget和不同Panel下(但这些panel的depth相同)的所有同depth的widget的渲染顺序目前还没有发现规律,但不管怎样都跟z轴貌似没啥关系,有高手可以补充哈