文章目录

  • 前言
  • 一、代码层面
  • 二、减少Rebatch和Rebuild
    • 1.Rebatch
    • 2.Rebuild
    • 3.优化点
  • 三、降低OverDraw
  • 总结

前言

最近笔者在找工作,面试过程经常被问到工作中做过哪些性能优化。这篇文章用以总结记录笔者在项目开发过程中,针对性能问题,需要注意的一些点。以及项目后期针对一些常见的影响性能的点做的一些优化。


一、代码层面

主要关注点:避免频繁申请堆内存,避免在一帧内进行大量耗时操作。

1)使用成员变量缓存,空间换时间
比如UI界面的节点用成员变量缓存起来,只用在初始化的时候获取一次。
比如每次计算红点逻辑保存到红点管理类的字典里,避免重复计算。
比如从表里频繁获取某些数据,获取后缓存起来,避免每次遍历整个表。
比如字符串拆分操作非常耗费性能,只拆分一次,然后缓存起来重复使用。
2)for/while等循环内,以及帧更新中避免创建内存,避免使用foreach。
3)使用泛型方法,避免装箱拆箱。
4)创建List和Dictionary时指定大小,避免内部扩容创建新数组。
5)使用StringBuilder进行字符串拼接。
6)使用对象池,回收可重复利用的对象,避免频繁创建和销毁对象。
7)在在网络IO中使用单独的线程来收发网络数据,使用循环缓冲区缓存数据。
8)耗时操作,异步处理,或者使用协程将消耗分散到每一帧。
9)一些不重要的刷新进行限帧操作,比如未参加战斗的怪物每5帧刷新一次。
10)去掉脚本中的空Update,空Update也会调用有额外性能消耗。

二、减少Rebatch和Rebuild

Unity会把要绘制的UI信息保存在Vertexhelper中,并且调用CanvasRenderer里面的方法进行绘制。
UGUI中的Canvas负责把它们包含的Mesh合批,生成合适的渲染命令发送给Unity图形系统。以上行为都是在Native C++代码中完成,我们称之为Rebatch或者Batch Build,当一个Canvas中包含的几何体需要Rebacth时,这个Canvas就会被标记为Dirty状态。
我们可以在Profiler中通过查看标志性函数Canvas.willRenderCanvases的耗时,来了解Mesh重建的性能消耗。

先简单说说什么是DrawCall和Batch:

DrawCall
即绘制调用命令,CPU在准备好渲染数据并设置渲染状态后,会通过Drawcall命令通知GPU进行渲染。

实际发送绘制指令之前,我们需要设置好所有必须的GPU状态,例如:Mesh数据(顶点位置、顶点法线等顶点数据)、着色器代码、纹理数据、混合设置以及其他的着色器属性等。这些都是在CPU上进行。

Batch
一些设置状态、改变状态的指令再加上一或多个绘制指令构成了我们所说的一次Batch。

可以点击Game窗口的Stats查看Batch的数量:

1.Rebatch

Rebatch发生在C++层面,是指Canvas分析UI节点生成最优批次的过程,节点数量过多会导致算法(贪心策略)耗时较长。对应SetVerticesDirty,当一个canvas中包含的Mesh发生改变时就触发,例如SetActive、transform的改变、 颜色改变、文本内容改变等等,canvas独立处理,互相不影响。消耗在对meshes按照深度和重叠情况排序、共享材质的检测等。

Batch以Canvas为单位,同一个Canvas下的UI元素最终都会被Batch到一个Mesh中。Batch前,UGUI根据UI材质以及渲染顺序重排,在不改变渲染结果的前提下,尽可能将相同材质的UI元素合并在同一个SubMesh中,以减少DrawCall。Batch只在UI元素发生变化时进行,合成的Mesh越大,耗时越大。重建对Canvas下所有ui元素生效,不论是否修改过。

5.2之后底层是多线程的,考虑到现在手机上都是多核,这部分消耗可能会小很多。不过对于复杂的UI,还是应该注意这块的消耗。

合批细节
1.计算每个渲染节点的深度depth
1)按照在Hierarchy节点的顺序,从上向下进行depth分析(深度优先原则);
2)跳过不用渲染的节点,比如active为false,image脚本Disable,Canvas不渲染的Layer等;
3)如果处于渲染状态且(网格)没有覆盖到其他节点,depth = 0;
4)处于渲染状态但是覆盖到其他节点,找到被覆盖节点中depth最大的元素A。
5)若节点的材质和贴图是否和A相同,则节点的depth等于A节点。否则A节点depth + 1;

2.根据节点的depth、材质(获取Instance ID)、贴图(Instance ID)对节点进行排序。
根据排序结果对depth、材质、贴图都相同的节点进行合批。
注意节点Position.z不为0时,视为3D UI,其子物体全部不参与合批,且打断前后合批。

2.Rebuild

Rebuild发生在C#层面,是指UGUI库中layout组件调整RectTransform尺寸、Graphic组件更新Material,以及Mask执行Cull的过程,耗时和发生变化的节点数量基本呈线性相关。

只有LayoutGroup的直接子节点,并且是 Graphic类型的(比如 Image 和 Text)会触发SetLayoutDirty。

Graphic改变的原因包括,基本的大小、旋转以及文字的变化、图片的修改等等,对应SetMaterialDirty。

发生Rebuild时会触发Rebatch。

3.优化点

1.Canvas动静分离,合理划分,按游戏类型和UI数量划分,太多也有额外消耗。
举例:跑马灯效果,可以在动态节点的父节点添加一个单独Canvas。

2.减少节点层次和数量,使用相同材质贴图的UI尽量保持深度相同,减小合批计算量。
举例:可以将一个Text的层级下面放一个其他图集的透明图片,将其层级垫高,使其与相同depth的Text节点进行合批。

3.修改Image的Color属性,原理是修改顶点色,会引起网格Rebuild,从而触发Rebatch。
可以通过修改shader颜色来实现,不会重绘,材质不变,没有Rebatch。
举例:颜色的渐变效果(颜色动画)可以通过动态修改材质的shader颜色来实现。

4.RectMask2D代替Mask。

5.少用layout,简单的布局RectTransform代替。

6.不显示的对象,不要SetActive,设置Canvas Group的alpha为0,scale为0,这样vbo(在显存中保存的 顶点信息)不会被清除。
或者CanvasRenderer.cull设为true,表示当UI的透明度为0的时候删掉网格和顶点。

7.使用图集,同个界面、同个功能的图在同一个图集。

8.慎用自带组件Outlien和Shaow,都是通过重复绘制多个Mesh实现的,其中Showdow绘制为原文本Mesh的2倍,而Outline为5倍,对渲染面数、顶点数,BuildBatch和SendWillRenderCanvases的耗时,Overdraw都有影响。

可以使用BMFont制作美术字。若对于某种字体每次出现都需要这两种效果,可以让美术同学直接把阴影和描边做到字体里。

三、降低OverDraw

Overdraw是指一帧当中,同一个像素被重复绘制的次数。Fill Rate(填充率)是指显卡每帧每秒能够渲染的像素数。在每帧绘制中,如果一个像素被反复绘制的次数越多,那么它占用的资源也必然更多。Overdraw与Fill Rate成正比,目前在移动设备上,FillRate的压力主要来自半透明物体。因为多数情况下,半透明物体需要开启 Alpha Blend 且关闭 ZTest和 ZWrite,同时如果我们绘制像 alpha=0 这种实际上不会产生效果的颜色上去,也同样有 Blend 操作,这是一种极大的浪费。

1.减少UI重叠层级,隐藏处于底下被完全覆盖的UI面板。
2.对于需要暂时隐藏的UI,不要直接把Color属性的Alpha值改为0,UGUI中这样设置后仍然会渲染,应该用CanvasGroup组件把Alpha值置零。
3.需要响应Raycast事件时,不要使用空Image,可以自定义组件继承自MaskableGraphic,重写OnPopulateMesh把网格清空,这样可以响应Raycast而又不需要绘制Mesh。
4.打开全屏界面,关闭场景摄像机。对于一些非全屏但覆盖率较高的界面,在对场景动态表现要求不高的情况下,可以记录下打开UI时的画面,作为UI背景,然后关掉场景摄像机。
5.裁掉无用区域,镂空,对于Sliced类型的Image可以看情况取消Fill Center。
6.慎用Mask组件和Outline、Shadow组件

总结

代码层面只要是空间换时间,避免频繁申请堆内存,避免在一帧内进行大量耗时操作。
UGUI层面:主要是降低DrawCall、减少Rebuild、减少OverDraw。

参考:
UGUI DrawCall合批细节
https://edu.uwa4d.com/lesson-detail/126/482/0?isPreview=false
https://zhuanlan.zhihu.com/p/340480771
https://blog.csdn.net/wanttokonw/article/details/121889261
Unity官方的UGUI优化指南读后总结
UGUI深入理解–性能优化总结
NGUI和UGUI对比及性能提升技巧
UGUI性能优化总结(花卷)

Unity 性能优化基础相关推荐

  1. Unity 性能优化:资源篇

    Unity性能优化 大的方面来说,通过Unity对于项目的性能优化大概可以分为下面几个部分: 资源 渲染 程序 项目配置 而在这个部分中,资源的性能优化属于最基础.最有效的优化手段,也是游戏开发者日常 ...

  2. Unity 性能优化(力荐)

    开始之前先分享几款性能优化的插件: 1.SimpleLOD : 除了同样拥有Mesh Baker所具有的Mesh合并.Atlas烘焙等功能,它还能提供Mesh的简化,并对动态蒙皮网格进行了很好的支持. ...

  3. 第一章:unity性能优化之内存优化

    目录 前言 unity性能优化之内存的优化 一.unity Analysis工具的使用. 二.内存优化方法 1.设置和压缩图片 2.图片格式 3.动画文件 4.模型 5.RenderTexture(R ...

  4. Unity性能优化 – 脚本篇

    最近开始进行Unity性能优化的工作,主要分为三类:CPU.GPU和内存.由于我们游戏的核心战斗是计算密集型,所以主要是受限于CPU.CPU的优化又分为渲染和脚本,本文将着重于脚本优化. 一般来说,优 ...

  5. 【SQL】关于SQL Server的性能优化——基础内容

    [一些网课后的笔记与后续学习的思考] 平时我们觉得查数据很慢,这个慢是什么意思? 就是在现有资源达到最大吞吐量的前提下,系统不能满足合理的数据请求的一些表现. 一.调优时,可以从以下五点考虑 ① 最小 ...

  6. Unity性能优化(2)-官方教程Diagnosing performance problems using the Profiler window翻译

    http://www.cnblogs.com/alan777/p/6135703.html Unity性能优化(2)-官方教程Diagnosing performance problems using ...

  7. 【Unity性能优化】静态资源优化——Audio优化

    文章目录 写在前面 1. 前言 2. 使用Asset Checker进行资源检测 3. Audio优化 3.1 启用Force to Mono 3.2 压缩格式与采样率 3.3 音乐加载类型 3.4 ...

  8. Unity性能优化 :合批篇

    前言 本系列为一些性能优化的小知识,是日常游戏开发中与性能表现的一些点,本篇为该系列文章的第二篇,前篇链接: 第一篇: Unity性能优化:资源篇 在早期Unity中,对于合批的处理手段主要是下面三种 ...

  9. 前端性能优化基础知识--幕课网

    作为一个前端小码农,在页面样式都能实现以后,就开始考虑:同一个效果,我该用什么样的方式和代码去实现它比较规范?前两天逛幕课网发现了两门课程–<前端性能优化-基础知识认知>和<前端性能 ...

最新文章

  1. python实例,python网络爬虫爬取大学排名!
  2. 【JOURNAL】城邦组诗之十二 - 心肠
  3. Ubuntu下安装DEB包时出现错误的解救方法
  4. 链表经典题:K个一组翻转链表
  5. 第六届蓝桥杯省赛javaB组真题及答案
  6. (转)Linux:使用libgen.h:basename,dirname
  7. html下拉菜单的子目录,html - 带有下拉菜单的子菜单的垂直下拉菜单 - 堆栈内存溢出...
  8. django-自定义过滤器
  9. SilverLight幻灯片
  10. HUAWER 华为5G无线数据终端 和 TP-LINK路由器AX6000连接及注意事项
  11. R语言学习笔记(一)
  12. java throw 和catch_Java catch与throw同时使用的操作
  13. 撤回的微信消息腾讯服务器有记录吗,教你如何查看对方已经撤回的微信消息
  14. R语言—90分钟从入门到精通
  15. TeamViewer和向日葵远控软件的个人使用感觉
  16. 科创板公司数据信息爬取
  17. 怎么写功能测试报告,分享专业的功能报告模板
  18. linux新手入门及安装全攻略(转载)
  19. 【Unity3D开发小游戏】专栏文章导读清单
  20. 用css3做出好看的盒子阴影

热门文章

  1. 使用Python将OV7725的RGB565图像数据转换为jpg图像
  2. lnk1120如何解决_fatal error LNK1120: 6 unresolved externals问题怎么解决?
  3. 《人工智能及其应用》课程笔记(四)第4章 非经典推理
  4. 二维数组作为参数传递问题
  5. AutoCAD 2007创建块
  6. 带你了解大数据时代的基本特征
  7. 【SPSS统计分析】运用spss软件进行问卷信度分析(附SPSS19.0简体中文版下载地址)
  8. 托福阅读基础训练方法
  9. 冒泡排序法和选择排序法比较(从小到大,升序)
  10. Mysql的常见面试题 + 索引原理分析