UGUI性能优化

UGUI的性能从三方面来优化

1、减少DrawCall(也是一种GUP优化)

2、从CPU方面优化

3、从GUP方面优化

4、UI的隐藏和显示

 

1.DrawCall方面:

UGUI提供一个图集的功能。把零碎的图片打包成一张大图。在使用的时候。读取大图里的数据。这样便于压缩图片占用的内存和减少DrawCall的消耗

UGUI会把相邻的同一图集的图片合并。从而达到减少DrawCall的效果

根据以上信息,可以得到图集分配的一些规则:

1、同一界面的元素,尽量放到一个图集里面

2、同一界面的元素分别在多个图集里面时。尽量把相同图集的元素放在一起。避免图集直接的交叉布置

3、通用的元素,放到一个或者几个共享的图集里面。这样便于降低加载时间

4、如果可以。把带透明通道的和不带透明通道的图片放在不同的图集。(这样可能会产生更多的DrawCall,所以在内存压力大,而GUP压力不大的时候可以这么处理)

 

2、CPU的优化:

1)、内存的优化:

Windows平台:选用DXT5格式。这个格式是带透明通道的

内存占用比。假设不压缩的大小为1

DXT5 : 0.25

Android平台:选用ETC2 8 BITS

ETC2 8 BITS : 0.25

如果使用ETC 4 BITS + 1BIT ALPHA ETC2 8BITS 能把内存降到:0.125。有兴趣的可以去找找Android平台使用ETC 4 BITS + 1BIT ALPHA ETC2 8BITS这种方式的具体操作流程

IOS平台:选用 PVRTC 4BITS

但是PVRTC 格式要求是方形的图集贴图

PVRTC 4BITS : 0.125

非方形的贴图会被转成16位RGB(A)的压缩格式。会带来颜色损失。

但是在项目中。发现用PVRTC 4BITS格式的图片会发虚,改用ASTC格式的就不会出现这样的问题

注:UGUI会自动把压缩格式的图打成方形。

高清图片。比如背景大图等。可以使用RGBA 32BIT格式。这个就是原图大小。没有压缩

对精度要求不高的大图。也可以压缩。方法如下:

1、在贴图的Import Setting。选择Texture Type为Advance。然后将Non Power of 2 设置成ToLarger或者其他格式。Unity会强制拉伸图标为2的N次幂

2、选择图标格式为Automatic Compressed

建议大图导出为JPG图片或者无透明的PNG格式

2)、删除不用的UI节点、动画组件及资源:在项目迭代的时候。可能有部分UI节点、动画、特效等资源失效。有些时候为了方便。直接把不用的东西隐藏掉。这样虽然看不见了。但是增加了内存和加载时间。所以不用的资源。一定要删除而不是隐藏

3)、Canvas.SendWillRenderCanvases或Canvas.BuildBatch占用过多的时间问题

在UI元素的大小、Color等属性发生改变时。Canvas会调用Canvas.SendWillRenderCanvases并且执行Canvas.BuildBatch。在Canvas中UI Mesh的顶点多的话。Canvas.BuildBatch将会出现较高的CUP消耗,

Canvas.BuildBatch是合并Canvas下UI的Mesh。并缓存起来。在Canvas下UI Mesh发生改变时。才会重新合并,Canvas.SendWillRenderCanvases的执行流程如下:

由CanvasUpdateRegistry监听SendWillRenderCanvases事件(图中1)。

1.进行深度排序(图中2)。

2.rebuild Layout。计算各元素的位置和大小

3.rebuild graphic。调用UpdateGeometry进行重建网格数据,UpdateMaterial更新材质信息

基于上面的网格更新原理,有一下几点建议:

1、使用尽可能少的UI元素。这里指的是删除不必要的节点和隐藏不用的节点。这样能减少深度排序和rebuild Layout的执行时间

2、尽量减少Rebuild的频率,将动态和静态的元素分离,放到不同的Canvas里面。

3、谨慎使用Text的Best Fit选项。这个选项可以动态调整字体大小以适应UI布局而不会超出边框,但是代价很高。Unity会为改元素用到的字号生成图元保存的Atlas里面,不但增加了额外的生成时间。还使字体的atlas变大

4、谨慎使用Canvas的Pixel Perfect选项,该选项会使得ui元素在发生位置变化时,造成layout Rebuild。(比如ScrollRect滚动时,如果开启了Canvas的pixel Perfect,会使得Canvas.SendWillRenderCanvas消耗较高)

5、除了Rebuild之外,UGUI处理Touch事件也可能成为性能热点。对应不需要接受输入的元素。一定要关闭Raycast Target选项

 

3、GUP的优化

一般来说。造成GPU的性能瓶颈一般在复杂的shader和overdraw造成的像素填充过多。一般都是用默认的UI材质。所以从overdraw方面考虑。overdraw主要是因为大量的UI重叠引起的。查看overdraw比较简单。在scene窗口选择overdraw模式。场景中越亮的地方。表示overdraw越高

降低overdraw可以做如下优化:

1、禁用开不见的UI。在被别的UI全部挡住时。可以考虑将系统禁用

2、不要使用空的Image,在Unity项目中。因为要用RayCast使用Graphi作为基本元素来检测touch。很多时候会用空的Image并将alpha设置为0来接收touch事件。这样会产生不必要的overdraw

可以使用一下脚本。只监听事件。不画网格

public class NoDrawingRayCast : Graphic
{
    public override void SetMaterialDirty()
    {

    }

    public override void SetVerticesDirty()
    {

    }

    protected override void OnPopulateMesh(VertexHelper vh)

    {
        vh.Clear();
    }

}

用RectMask2D替换Mask。这样会节约两个DrawCall。

4、隐藏和显示

UI切换的时候,有两个地方非常耗时,一个是SetActive,另外一个则是SetParent。

SetParent暂时没有好的处理方法

SetActive可以在切换UI的时候。不把UI 设置SetActive(false),而是设置UI的Layer。让UI摄像机看不到此UI。UI有个特性就是:必须设置Canvas的Layer才会生效。所以必须有一个用于放置隐藏UI的Canvas。把所以需要隐藏的UI都放置在这个Canvas下面。但是这样有一个问题就是UI上的特效还能被看见。在Scene场景中。隐藏的UI会叠加在正常显示的UI上方。不方便调试。也需要动态的显隐特效,增加逻辑的复杂度。

解决方法:在远处设立一个用于放置隐藏UI的Canvas,并且带独立的摄像机。把摄像机的显示层级设置到最低。这样就能解决上面两个问题

由于只是设置了UI的Layer。并没有真正的把UI隐藏掉。UI上面的脚步逻辑都是在运行的。所以在Update、回调事件这类函数里面。必须要判断UI是否在显示状态。然后再选择是否往下执行

 

以上就是UGUI的性能方面的总结。性能的优化是在各种选择直接做一个适合自己项目的平衡。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值