对Unity UI系统的一些总结

目前用的最多的UI系统可能就是UGUI和NGUI,众所周知这两套UI系统的主持开发是同一人,所以这两套UI的设计有很多的相似点,它们分别采用C++和C#开发,理论上是UGUI的性能会更好一些

如果有同学看过它们的源代码就会发现,它们的设计思想其实都是将Canvas或者UIRoot下的UI元素合并成一个mesh再着色渲染,然后每一帧去检测是否有UI发生了改变,如果有改变就需要重构这个mesh,所以基于这样的思想,我们就需要思考如何设计UI系统,对于一个界面而言,我们通常需要考虑动静分离,所谓的动静分离就是需要看这个UI是否有可能每帧都会改变,比如玩游戏时的操作轮盘、技能\普攻按键,那么我们就需要把这些可能每帧都会变化的UI放到一个Canvas下,如果不这样做分离,那么这个mesh会非常大,每帧都要重构需要耗费不少性能,动静分离之后,就只有动态mesh在重构,静态mesh(比如设置、菜单按钮等不经常操作的UI)就不会参与其中,减少不必要的性能消耗,所以如果发现某个Canvas下面UI特别多的话,也需要考虑对其做拆分,避免因为某一个小改动导致整个大mesh的重构

做完动静分离,我们通常还需要考虑两种界面,一是系统弹窗界面,二是页面切换的加载界面,通常会将系统弹窗界面的深度值大于加载界面,最终我们通常需要规划出至少这四种Canvas

设计完之后我们有时候还要继续思考对UI的进一步优化:

1.这两套UI都会有帮助我们合批的代码,什么是合批?合批就是把相同材质球、shader、贴图的UI渲染请求合并到一个drawcall里面,不过两者都有要求:UGUI是需要Hierarchy中相邻的两个UI元素,NGUI则需要同一UIRoot下深度相邻的两个UI元素,如果在做UI的时候考虑到合批的加入,会让我们的渲染更高效

2.图集:这个相信大家都不陌生,基本都用过,它的思想和合批类似,也是将需要多次渲染的多个图片合并到一起变成只渲染一张图片,从而减少drawcall,UGUI和NGUI都有自己的图集工具,NGUI下拉菜单里有,我现在用的2020.3.4,UGUI需要在package manager里面下载2D Sprite,然后在Project Settings->Editor->Sprite Packer里面开启图集,不过需要注意的一点是,NGUI打出来的图集没有做到与透明通道的分离(需要自己弄),通过将透明通道分离+使用shader让这两张图片融合即可,这时候加载所需要占用的内存会大大减少,透明通道分离在UGUI内部已经帮你完成了,图集打出来之后不要勾选Generate Mip Maps ,也不要勾选Read/Write Enabled,否则加载的时候会占用更多内存,另外需要注意的是:UGUI需要打包成图集的图片不能放在Resources文件夹内,建议分辨率较大的图片就不要放入图集里了

3.scrollview的优化,众所周知UGUI的scrollview的性能比较差,一旦加载的item很多,上下滑动就会有较明显的卡顿,这是因为这么多item构成的mesh在滑动中不断重构导致的,比较推荐的做法是做个对象池,比可视范围内多几个item,然后轮询加载,这样可以优化mesh的大小

4.UGUI中如果想要某个sprite不渲染,即使没有附加图片,它还是会渲染,正确做法是让它透明度为0,然后勾选Cull Transparent Mesh或者删除不必要的元素

5.UGUI里减少Mask的使用,原本同一图集里的UI可以合批,仅需一个drawcall渲染,如果加入Mask,就会将一个UI整体分割成了Mask下的子UI与其他UI,两者只能各自进行层级合并,这样至少要两个drawcall,故Mask尽量少用

6.UGUI里我们每添加一个UI组件的时候可能都会默认勾选了Raycst,因为它会每一帧都去检测所有勾选了这个的UI组件,这样性能消耗较大,所以某些不需要点击事件的UI我们尽量去掉Raycast的勾选

7.另外对于UI的图片资源比较重要的是选择合适的压缩格式,这个我会另外在Unity优化总结里面提到

猜你喜欢

转载自blog.csdn.net/qq_33805569/article/details/122682994
今日推荐