Unity UI性能优化技巧
本文将介绍一些提升Unity UI性能的技巧。更多优化技巧,可以观看Unity工程师Ian Dundore在Unite Europe 2017的演讲《使用Unity性能提升技巧》。
1.划分画布
问题:UI Canvas上有一个或多个元素变化时,会污染整个画布。
画布(Canvas)是Unity UI的基本组件。它会生成网格来呈现放置在画布上的UI元素,当UI元素变化时,它会重新生成网格并向GPU发起绘图调用,从而显示出UI。
生成这些网格会消耗大量性能,需要将UI元素收集到批处理中,从而尽可能减少绘图调用。因为批处理的生成过程性能消耗较大,通常只在必要时候才重新生成。问题在于,当画布上有一个或多个元素变化时,必须重新分析整块画布,才能得到绘制元素的最优方法。
许多用户将整个游戏的UI都放到一块画布,上面摆放了成百上千个元素。因此当修改其中一个元素时,会产生持续数毫秒的CPU使用量飙升情况。
解决方案:划分画布
每块画布上的元素都与其它画布的元素相隔离,所以我们可以使用工具来切分画布,从而解决Unity UI的批处理问题。
我们也可以通过嵌套画布来解决,这样允许设计师创建大型分层UI,而且不必担心不同内容出现在多个画布上。子画布的内容与父画布和同级画布相互隔离,它们会保持自带几何体,执行自己的批处理。
当使用子画布分离画布时,尝试根据画布更新时间来分组。例如:分离动态元素和静态元素。
2.Graphic Raycaster的最佳用法
问题:Graphic Raycaster有哪些最佳用法?
Graphic Raycaster组件能够将输入内容转换为UI事件,它会把触屏输入转为事件,然后发送给相关UI元素。每个接收输入内容的画布都需要Graphic Raycaster组件,包括子画布。
尽管该组件名为Graphic Raycaster,但它却不是个光线投射器,默认情况下它只会测试UI图形。该组件会获取特定画布上输入信息相关的UI元素集,然后执行交点测试,它会针对Graphic Raycaster的画布上每个交互式UI元素的RectTransform,检查输入事件发生的位置。
解决方案:关闭静态或非交互式元素的Raycast Target。
例如:有一个带文字的按钮,关闭该元素的Raycast Target会直接减少Graphic Raycaster每帧进行的交点测试次数。
问题:有时候Graphic Raycaster会充当光线投射器使用。
如果将画布上的渲染模式设为世界空间摄像机(Worldspace Camera)或屏幕空间摄像机(Screen Space Camera),此时可以设置阻挡遮罩(Blocking Mask)。
阻挡遮罩决定光线投射器是通过2D物理还是3D物理投射光线,从而了解特定物理对象是否阻挡用户与UI交互。
解决方案:通过2D或3D物理投射光线会消耗不少性能,所以要谨慎使用该功能。
尽量减少Graphic Raycaster的数量,不要将Graphic Raycaster添加到非交互式UI画布上,因为这样做无法检查交互事件。
3.避免使用Camera.main
问题:世界空间画布需要了解交互事件来自哪个摄像机。
当设置画布进行渲染时,不管该画布是在世界空间还是摄像机的屏幕空间,都可以指定用于为UI中Graphic Raycaster生成交互事件的摄像机。渲染模式为“Screen Space - Camera”的画布需要使用该设置,该设置名为“Render Camera”。
然而在渲染模式为“World Space”的画布上,该设置是可选的,名为“Event Camera”。
如果将世界空间画布的Event Camera字段留空,这不意味着该画布不会接收事件。它会使用游戏的主摄像机。为了确定哪个摄像机是主摄像机,该画布会访问Camera.main属性。
根据Unity所使用的代码路径,每帧中每有一个Graphic Raycaster和世界空间画布,该画布会访问7到10次Camera.main。每次访问Camera.main都会调用Object.FindObjectWithTag。这个做法在运行时并不合适。
解决方案:避免使用Camera.main
缓存摄像机的引用,然后创建系统来跟踪主摄像机。如果使用世界空间画布,要指定Event Camera,不要将该属性留空。如果需要修改Event Camera,编写代码来更新Event Camera属性。
4.避免使用布局分组
问题:每个影响布局的UI元素都会至少执行一次GetComponents调用。
当修改布局系统的一个或多个子元素时,会使布局变脏。修改后的子元素会使拥有该元素的布局系统(Layout System)无效化。
简单介绍一下布局系统:布局系统是一组连续的布局分组(Layout Group),它们在布局元素(Layout Element)之上。布局元素不只是名为Layout Element的组件,它们还包括UI图像、文字和Scroll Rect组件,而且Scroll Rect同时也是布局分组。
回到问题本身,每个使布局变脏的UI元素都会至少执行一次GetComponents调用,该调用会在布局元素父对象上寻找有效的布局分组。找到有效布局分组后,它会继续遍历Transform层级,直到停止寻找分组或是到达层级的根部分,无论先满足哪个条件都会停止寻找过程。因此。每个布局分组会给每个子布局元素的改变过程添加一次GetComponents调用,使嵌套布局分组的性能变差。
解决方案:避免使用布局分组。
使用锚点进行比例布局。在拥有动态元素数量的活跃UI上,考虑编写代码来计算布局,仅在需要时运行该代码,而不是每次发生改变的时候。
5.巧妙地聚集UI对象
问题:用错误的方法聚集UI对象。
通常情况下,用户通过重置父对象来聚集UI对象,然后再禁用对象,但这样会造成不必要的污染。
解决方案:首先禁用对象,然后将其父对象重置为对象池。
这样操作仅会改变一次原有的层级,但在重置父对象时,要避免二次改变原有的父对象,也不要改变新的层级。如果要从对象池移除对象,首先重置它的父对象,然后更新数据,再启用该对象。
6.如何隐藏画布
问题:如何隐藏画布?
有时需要隐藏UI元素和画布,要怎样高效完成该任务呢?
解决方案:禁用Canvas组件。
禁用Canvas组件会阻止画布向GPU发起绘图调用,所以该画布不再可见。然而,此时该画布不会丢弃它的顶点缓冲区,它会保留所有网格和顶点,当重新启用时不会触发重构过程,它只会重新绘制画布内容。
此外,禁用Canvas组件不会触发Canvas层级上性能消耗较大的OnDisable/OnEnable回调。禁用子组件时要小心,注意它是否运行性能消耗较大的每帧代码。
7.UI元素上Animator的最佳用法
问题:如何在UI上使用Animator?
Animator每帧都会改变元素,即使动画中的数值没有变化。Animator没有空指令检查。
解决方案:
只在频繁变化的动态元素上加入Animator。对于很少变化的元素,或是仅响应事件时才变化的元素,请自行编写代码或补间系统,你可以在Asset Store资源商店找到许多补间系统插件。
小结
提升Unity UI性能的技巧就为大家分享到这里,更多关于Unity的优化技巧请访问Unity官方中文论坛(UnityChina.cn) !
文章来源于unity微信公众号:Unity官方平台
原文链接: Unity UI性能优化技巧
Unity UI性能优化技巧的更多相关文章
- Android UI性能优化详解
设计师,开发人员,需求研究和测试都会影响到一个app最后的UI展示,所有人都很乐于去建议app应该怎么去展示UI.UI也是app和用户打交道的部分,直接对用户形成品牌意识,需要仔细的设计.无论你的ap ...
- JavaScript 如何工作:渲染引擎和性能优化技巧
翻译自:How JavaScript works: the rendering engine and tips to optimize its performance 这是探索 JavaScript ...
- Java程序性能优化技巧
Java程序性能优化技巧 多线程.集合.网络编程.内存优化.缓冲..spring.设计模式.软件工程.编程思想 1.生成对象时,合理分配空间和大小new ArrayList(100); 2.优化for ...
- Python代码性能优化技巧
摘要:代码优化能够让程序运行更快,可以提高程序的执行效率等,对于一名软件开发人员来说,如何优化代码,从哪里入手进行优化?这些都是他们十分关心的问题.本文着重讲了如何优化Python代码,看完一定会让你 ...
- Python 代码性能优化技巧(转)
原文:Python 代码性能优化技巧 Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化. ...
- Python 代码性能优化技巧
选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化 ...
- Unity 绘图性能优化 - Draw Call Batching
Unity 绘图性能优化 - Draw Call Batching Unity官方链接:http://docs.unity3d.com/Manual/DrawCallBatching.html 转载请 ...
- JavaScript 性能优化技巧分享
JavaScript 作为当前最为常见的直译式脚本语言,已经广泛应用于 Web 应用开发中.为了提高Web应用的性能,从 JavaScript 的性能优化方向入手,会是一个很好的选择. 本文从加载.上 ...
- MySQL 性能优化技巧
原文地址:MySQL 性能优化技巧 博客地址:http://www.extlight.com 一.背景 最近公司项目添加新功能,上线后发现有些功能的列表查询时间很久.原因是新功能用到旧功能的接口,而这 ...
随机推荐
- Desktop Central 的移动设备管理功能
Desktop Central 的移动设备管理功能1.移动应用程序管理设备管理不会仅仅只是配置策略.检索资产信息和保护设备.应用程序管理与设置员工的移动设备一样重要.使用 Desktop Centre ...
- 20175229张智敏 Arrays和String单元测试
Arrays和String单元测试 1.具体要求: 在IDEA中以TDD的方式对String类和Arrays类进行学习 测试相关方法的正常,错误和边界情况 String类 charAt split A ...
- Django模板标签
一.模板标签 1.模板标签是在模板中运用python语言的实现,如for循环,if语句 2.模板标签的运用 2.1在teacher模板下创建students_list模板, 在teacher视图中国创 ...
- 解决sqlserver数据库表空间不自动释放问题
在项目中遇到了sql server数据库经过频繁地删减数据后,查询变慢的问题. 我把数据导到另一个库中,发现查询就很快. 查了下原因,根本原因是删除数据并不释放表空间,日志文件太过巨大的原因. 网上查 ...
- SEO常用命令大全
SEO常用单个命令如下: link: 指某个特定网站的外部链接,这是一个主要获取排名和权重的主要因素. site: 呵呵,这个是经常用到的了,它是指某个特定网站收录情况. 用法:site: www. ...
- 解决.Net Core跨域问题
什么是跨域?浏览器从一个域名的网页去请求另一个域名的资源时,域名.端口.协议任一不同,都是跨域 跨域的几种情况 1.端口和协议的不同,只能通过后台来解决 2.localhost和127.0.0.1虽然 ...
- webpack踩坑--webpack 2.x升级至4.x
一.安装webpack-cli,webpack@4.26.1 1.npm install webpack-cli -D 2.npm install webpack@4.26.1 -D 二.踩坑 执行n ...
- vue学习-自动行合并的table
测试的效果 测试的html源码截图 v-table在tableGroup.js中定义,以下就render方法,行的所有单元格都在tableGrouper.js中处理 render:function(h ...
- 代码文档生成工具Doxygen的使用备忘
Doxygen备忘 下载与安装 一般步骤 生成配置文件Doxyfile: doxygen (-s) -g 建立目录结构, 比如Doxyfile文件\doc文件夹(输出)\src文件夹(放代码) -&g ...
- lambada
一.动态创建 ParameterExpression parameter = Expression.Parameter(typeof(User), "u"); //创建委托 Mem ...



