游戏蛮牛学习群(纯技术交流,不闲聊):539178957
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

首页   >   博客   >   sheng2008

UGUI减少DrawCall及CPU和GUP的优化

个人分类: Unity | 2018-7-23 06:24
0 个评论 | 阅读 158 | 收藏 | 举报
UGUI的性能从三方面来优化
1、减少DrawCall(也是一种GUP优化)
2、从CPU方面优化
3、从GUP方面优化

1.DrawCall方面:
UGUI提供一个图集的功能。把零碎的图片打包成一张大图。在使用的时候。读取大图里的数据。这样便于压缩图片占用的内存和减少DrawCall的消耗
UGUI会把相邻的同一图集的图片合并。从而达到减少DrawCall的效果
根据以上信息,可以得到图集分配的一些规则:
1、同一界面的元素,尽量放到一个图集里面
2、同一界面的元素分别在多个图集里面时。尽量把相同图集的元素放在一起。避免图集直接的交叉布置
3、通用的元素,放到一个或者几个共享的图集里面。这样便于降低加载时间
4、如果可以。把带透明通道的和不带透明通道的图片放在不同的图集。(这样可能会产生更多的DrawCall,所以在内存压力大,而GUP压力不大的时候可以这么处理)

2、CPU的优化:
1、内存的优化:上一章 “UGUI图片格式”中讲述了在不同平台上用不同的压缩格式及图片的大小问题
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。

以上就是UGUI的性能方面的总结。性能的优化是在各种选择直接做一个适合自己项目的平衡。
自动判断 中文中文(简体)中文(香港)中文(繁体)英语日语朝鲜语德语法语俄语泰语南非语阿拉伯语阿塞拜疆语比利时语保加利亚语加泰隆语捷克语威尔士语丹麦语第维埃语希腊语世界语西班牙语爱沙尼亚语巴士克语法斯语芬兰语法罗语加里西亚语古吉拉特语希伯来语印地语克罗地亚语匈牙利语亚美尼亚语印度尼西亚语冰岛语意大利语格鲁吉亚语哈萨克语卡纳拉语孔卡尼语吉尔吉斯语立陶宛语拉脱维亚语毛利语马其顿语蒙古语马拉地语马来语马耳他语挪威语(伯克梅尔)荷兰语北梭托语旁遮普语波兰语葡萄牙语克丘亚语罗马尼亚语梵文北萨摩斯语斯洛伐克语斯洛文尼亚语阿尔巴尼亚语瑞典语斯瓦希里语叙利亚语泰米尔语泰卢固语塔加路语茨瓦纳语土耳其语宗加语鞑靼语乌克兰语乌都语乌兹别克语越南语班图语祖鲁语 自动选择 中文中文(简体)中文(香港)中文(繁体)英语日语朝鲜语德语法语俄语泰语南非语阿拉伯语阿塞拜疆语比利时语保加利亚语加泰隆语捷克语威尔士语丹麦语第维埃语希腊语世界语西班牙语爱沙尼亚语巴士克语法斯语芬兰语法罗语加里西亚语古吉拉特语希伯来语印地语克罗地亚语匈牙利语亚美尼亚语印度尼西亚语冰岛语意大利语格鲁吉亚语哈萨克语卡纳拉语孔卡尼语吉尔吉斯语立陶宛语拉脱维亚语毛利语马其顿语蒙古语马拉地语马来语马耳他语挪威语(伯克梅尔)荷兰语北梭托语旁遮普语波兰语葡萄牙语克丘亚语罗马尼亚语梵文北萨摩斯语斯洛伐克语斯洛文尼亚语阿尔巴尼亚语瑞典语斯瓦希里语叙利亚语泰米尔语泰卢固语塔加路语茨瓦纳语土耳其语宗加语鞑靼语乌克兰语乌都语乌兹别克语越南语班图语祖鲁语 有道翻译 百度翻译 谷歌翻译 谷歌翻译(国内) 翻译 朗读 复制 正在查询,请稍候…… 重试 朗读 复制 复制 朗读 复制 via 谷歌翻译(国内)
0 0

作者的其他最新博客

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册帐号
返回顶部