unity对游戏ui的了解一

本文只是UWA直播的记录,感兴趣的小伙伴可以去看视频,本文只是为了加深记忆。

https://blog.uwa4d.com/archives/1875.html

元素更新

相同点:填充ui顶点数组

  1. 无论ugui还是ngui都有对应的类存储ui的顶点属性,这个顶点类会跟每个ui的顶点元素对应绑定。会有几个数组去存当前ui的UI属性,当ui发生变化是要通过对应的类,去填充对应的数组,即当顶点数越多,需要更新的点就变多,填充数组的过程也就越长。ngui:UIGeometry;ugui:VertexHelper;
    1. 对于"动态"的元素,尽量少用outline,和Tiled Sprite
      1. outline:会把四边形重复5遍,导致顶点数*5,也会导致顶点数比较多。更新比较慢
      2. Tiled:image type,会自动复制出很多三角形和顶点
    2. “动态”长文本,运行时修改文字,哪怕没有outline一个text中文字过多(文本优化)。
    3. 尽量减少这些对象(1,2中提到的)的Canvas的重建,每次重建也会从新填充所有顶点数据。

不同点:更新方式

  1. NGUI:UIPanel.LateUpdate是NGUI刷新的主逻辑,负责UI更新的操作,每帧都会执行,并且每帧都会有UIPanel.UpdateWidgets的调用(更新每一个激活状态Widget的位置,大小等,都会有一个更新和获取的过程)。如果在更新的过程中发现widget发生了变化,就进行一些列的操作。即使widget没有变,那么也会产生对应的轮询。所以说在NGUI中有大量的元素在里面,哪怕是完全静止的也会有性能开销。
  2. UGUI:Canvas.SendWillRenderCanvas是UGUI刷新UI的方法。由两个队列进行:m_LayoutRebuildQueue和m_GraphicRebuildQueue;这两个队列会记录layout相关以及Graphic相关的元素的变化。在渲染之前会在SendWillRenderCanvas回调中处理这两个队列。也就是说在ui没有变化的时候消耗是很小的。

应用场景

  • 动态的HUD缓存机制的影响:在使用HUD时,考虑到性能,一般会缓存一部分对象,把不用的不用的对象隐藏起来,“隐藏”的方法有很多,不同的UI下不同的方案,对性能也会产生影响。
  1. NGUI:
    1. 适量元素:Color.a = 0, 移出。Scale = 0的话仅仅是网格变成0,但是顶点数还在。drawcall也会提交
    2. 大量元素:setActive(false),上面提到,激活状态widget也会消耗轮询的时间,所以大量的元素最好就是SetActive=false
    3. Timer + 2级缓存:
  2. UGUI:
    1. Scale = 0 (会把顶点移出)或者 Alpha Group = 0,(CanvasGroup.alpha =0)或者禁用Canvas组件:这三种方式都不会有顶点的重建,不会触发ui的更新。但是会减少面数和重绘。还不会触发setActive的回调。
    2. 不要使用color.a = 0,因为在这种变化对于面片数没有任何变化,也就不能降低drawcall,对overdraw也没有任何效果。

Draw Call的合并规则

渲染顺序

NGUI:widget的depth,以UIPanel为单位,根据depth的大小,去做排序,把相同材质的进行合并。

UGUI:hierarchy(黑盒:比较难分析出为什么drawcall没有合并)

  1. 重叠检测:当两个ui(比如按钮),重叠的时候,批处理就取消了!!
  2. 分层合并,在UGUI中有“层”的概念,当“层”一样,且图集一样是,会进行合批处理,但是当有一个ui多出一层时,合批就会取消!!!

调试工具

NGUI:DrawCall Tool

UGUI:Frame Debugger

影响:

  1. UGUI不好处理的元素:
  2. 不规则的图标,可能导致ui的重叠。
  3. UI元素的旋转,当旋转之后判断重叠会是一个很大的矩形。一旦ui重叠,就会限制drawcall的合并(旋转后反而batchs减少了,什么鬼)
  4. 动态遮挡,
  5. 3D UI 一旦ui旋转,就容易发生重叠,导致drawcall上升,因为在计算重叠的时候,是把3dUI投影到2d上后计算的,旋转后投影面会变大。导致合并失败。

NGUI不好处理的元素:

  1. 就是要有些手动调整

网格更新机制

NGUI:UIPanel.LateUpdate两种更新方式

  1. UIPanel.FillDrawCall 更新单个DrawCall
  2. UIPanel.FillAllDrawCall更新所有DrawCall,这个函数一旦出现,如果UIPanel比较复杂,更新的开销就很高,这是容易出现峰值的地方。

UGUI:Canvas.BuildBatch更新所有UI,5.2之后ui的合并放到了子线程中,一旦子线程ui的网格开销比较高,就会在主线程中看到1,2两个函数。

  1. WaitingForJob
  2. PutGeometryJobFence
  3. BatchRenderer.Flush:打开多线程渲染后1,2消失,会出现BatchRenderer.Flush

建议:当优化UGUI的时候可以关闭多线程渲染,然后观察1和2,当1和2消失后,就是一个比较好的状体了。

对界面的影响

UGUI

拆分Canvas很重要原则:动静分离,修改ui会导致整个canvas刷新。

NGUI

控制FillAllDrawCalls

拆分UIPanel

比较

  1. 功能界面的DrawCall控制:NGUI>UGUI
  2. 功能界面的网格更新:NGUI>UGUI
  3. 动态HUD界面的网格更新控制NGUI<<UGUI
  4. 堆内存的优化NGUI<<UGUI

优化部分下一次写吧...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值