Ngui和Ugui的区别

NGUI的元素更新:

            UIPanel.LateUpdate采用轮询的方式,每帧都会执行,并且每帧都会有UIPanel.UpdateWidgets这个函数的调用,做的事情就是对这些UI元素的位置、缩放等信息的获取,也就是即使没有变化的UI元素,也会有正常的轮询操作的开销。

UGUI的元素更新:

            Canvas.SendWillRenderCanvas则不是通过轮询的方式,而是通过两个队列:m_LayoutRebuildQueue和m_GraphicRebuildQueue。这两个队列会分别记录Layout和外观(Graphic)发生变化的UI元素,在渲染之前,会在这个回调函数里去处理这两个队列里的元素,即分别进行Rebuild。所以,在UGUI中如果有大量UI元素但是是静态的,则不会有持续开销。

对动态HUD缓存机制的影响(缓冲池)

        -NGUI

                *适量元素(比如血条就需要20、30个让它在池子中,不停出现消失的话)可直接通过Color.alpha = 0去隐藏。这样UI元素的顶点数可被移除掉,也可节省一部分SetActive的开销

                *若有大量激活的UI元素在缓冲池中,开销较大,这时可以考虑二级缓存,在进入战斗的时候依旧可以通过上边的让a=0或1的方式去切换;但是当退出战斗后再让缓冲池里的元素按批的去SetActive(false)禁用掉,这样就可以保证出了战斗之后,这些缓冲池里的元素不会有持续的开销。

                注意:尽量不用Scale = 0 ,这仅仅把网格Scale为0,但顶点数还在,DC依旧会提交!

        -UGUI

                *Scale = 0,或挂一个Alpha Group = 0,这两种均可去掉元素的顶点,且无SetActive这种额外开销。

                注意:但尽量不用Color.alpha = 0这种把透明度设为0的方式,因为这相当于贴了一个透明面片还是会被画到场景中,对DC和OverDraw无影响。   

            

DrawCall合并规则

& 渲染顺序

            -- NGUI:depth

                    通过手动去设置Depth的值,NGUI就会根据值的大小以UIPanel为单位进行一个排序,相同材质的去做合并

            -- UGUI:hierarchy

                    *重叠检测(两个Button的例子)

                    *分层合并(如下图,每个颜色代表一个图集之类的可以合并合批,可以发现第一行相同的颜色进行了合并因为它们层能对应;第二行则不能,因为右侧加了一层黑色,黑色是第0层,而左侧依旧蓝色是第0层,所以层不能对应了,DC就高了;第三行,两边又都有了黑色,所以层又能对应了,就合并了)     

                    

& 调试工具

            -- NGUI:DrawCall Tool

            -- UGUI: Frame Debugger

              

网格更新机制 

    NGUI:UIPanel.LateUpdate两种更新方式

                -- UIPanel.FillDrawCall  更新单个DrawCall

                -- UIPanel.FillAllDrawCall 更新所有DrawCall

    UGUI:Canvas.BuildBatch 更新所有DrawCall

                -- WaitingForJob

                -- PutGeometryJobFence

                -- BatchRenderer.Flush(开了多线程渲染之后)  所以做优化时建议先关闭多线程渲染,然后去观察①②两个函数

综上,在选择时,可以进行NGUI和UGUI的混用。

    在制作功能界面时,DrawCall控制 NGUI>UGUI

    在功能界面的网格更新控制,NGUI >UGUI

    在动态HUD界面(如血条,伤害数字,弹出的一些文本等)的网格更新控制,UGUI >> NGUI(因为UGUI网格合并这块的算法是用C++做的,所以会比在C#做的快很多,而且C#难免会触发一些堆内存的问题)

    所以,战斗外用NGUI,战斗内用UGUI。

一般,DC控制在30ms以内就比较好 

降低界面的渲染开销 

   ===》DrawCall

            -UGUI

                    *Z值 != 0 (Unity5.x之后)的情况本来能合批的,也不能合批了,即限制:只能在herighy里相邻的,并且是相同图集的UI元素才可以进行合并。(eg:z=0时,本来所有红色合并一个,白色合并一个。但是z≠0后,因为在herighy层第一组的红色是和第二组的白色挨着的,第二组的红色和第三组的白色是相邻的,因此不能进行合并了)

                                    

                                * 未“隐藏”元素:Null Sprite , Color.alpha = 0依然会被渲染

                 

                                * Hierarchy的穿插 + 重叠    (如下图,有时候item的size不合适,可能会导致红点和旁边的icon重叠了,导致不能合并DC,看起来没有重叠,但实际上线框是重叠了的话 )(解决:把Icon 和 红点分别放在不同节点下,这样即使有重叠也可以合并了)(然后再去写脚本去对应每个红点和icon之间的对应关系即可)

                 

             -NGUI

                        * UITexture 少用(因为它一般不能和其他合并,除非2张一模一样)

                        * 未“隐藏”元素:Scale = 0

 ===》OverDraw

            * 减少UI层叠

                * 不用Image检测事件

 ===》降低界面的更新的开销

            * 动静分离

                * 降低更新频率

                   * 避免“敏感”操作

                            ——NGUI  元素的隐藏显示引发FillAllDrawCalls(整个网格重建)

                                    比如下图知识点击了这个技能弹出一个遮罩,其他元素都不变,就会引发一个10ms的峰值。

               FillAllDrawCalls常见原因:

                    -------添加、删除元素时,穿插了其他的UIDrawCall

                    -------添加、删除的元素自成一个UIDrawCall

                避免方式:

                        通过 scale = 0 或 alpha 接近0 来“隐藏”(因为这样网格还在,DrawCall也在,不会打乱)

            举例说明:当用SetActive或alpha = 0的时候,NGUI的规则是从UIPanel中移除。而这会导致穿插!再如,每个DC都有范围,比如当前插入的DC depth是5~100,当加入一个depth为10的元素时,理论上应该插入到这里,但是如果它与当前DC图集不一致不能合并,则NGUI的规则是会执行Rebuild,重建整个UIPanel!!

                   * 优化选项(NGUI)

                        === Static  在UIPanel上如果勾选了这个选项,则可节省轮询的开销。  优化移动UIPanel时! (比如把一个很复杂的背包的UIPanel勾选之后,那么在移动这个UIPanel的时候,它下边元素则不会去计算位置,因为它是跟着这个Panel在动)

小Tip:可以设置一个不参与Camera渲染的Layer,然后当需要隐藏的时候,把当前元素或物体的Layer设置为这个不渲染Layer,这没有开销。
 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值