UGUI优化实践
上周挂掉腾讯三面的时候被点去好好看看UGUI优化部分的东西,咱一直很听劝,就拿着以前用UGUI做的游戏研究了一下。
不看不知道,以前做的UI真是把坑踩完了,一个卡牌仓库连60帧都稳不住,真是让人流汗…
下面是优化的完整思路(注:仅针对于减少batches)
优化前
这是一个明日方舟同人游戏的卡牌仓库界面,所有卡牌都绘制在一个横向的ScrollView上。我曾将相关纹理打包图集,但并没有做任何其他的优化处理
进行此次优化前,场景绘制的总批次为879,每张卡片占用11Batches,没有发生任何的合批。编辑器运行无法稳定在60FPS。
优化流程
- 将所有可以替换的RawImage替换为Image。这是因为即便使用同一图集的不同纹理,多个RawImage也不会进行合批
- 总批次879 -> 737
- 每张卡牌独占10个Batches(每张卡的2个Image进行了合批)
- 将所有Sprite为空的图像填充上同图集中全白的图像。这是因为即便材质相同,空Sprite图像和有Sprite的图像也不能合批(视作非同图集的纹理)。
- 总批次717 -> 474
- 每张卡牌独占6个Batches
- 用CanvasGroup来管理“未解锁”和解锁卡牌的UI元素。因为即便是被遮挡的元素也会被渲染,造成性能损耗,而通过CanvasGroup设置为透明的元素则不会被渲染。(只要没有勾掉默认开启的Cull Transparent Mesh)
- 总批次474 -> 210
- 每张卡牌独占2/4个Batches
- PosZ置零+移除Rect Mask 2D
- 当UGUI元素的z轴不为0时或者旋转角不为90的整数倍时,分批的Bounds检测失效。即视为所有组件重叠在一起,渲染顺序严格按照Hierarchy顺序。该项目设计时单纯靠将加载进来的卡牌的父物体设定为带有Layout组件的物体PosZ不为零,无法合批。故添加一行代码,加载物件时将PosZ置零。
- Mask内的元素可以合批,但是Mask内外的元素不可以。对每一张卡牌都用Mask遮罩导致不同卡牌之间无法合批,应该去除组件。(我在此处找到了不打断合批的Mask解决方案)
- 总批次210 -> 23
- 卡牌不再独占Batch
- FPS基本稳定在200以上
- 对象池动态加载对象。原方案是一次性加载所有卡牌,没有看到的卡牌就直接挂在画面之外。如果只是想减轻渲染压力的话,将画面外的整张卡牌都用CanvasGroup隐藏就行了,但是追求更好性能的话还是要用对象池。(暂未实现)
相关资料
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 活木雕舟!
评论