破解技术难题,Unity官方性能优化和企业服务是如何工作的?

GameLook报道/11 月 16 –20 日,中国 Unity 线上技术大会以直播形式召开,为广大开发者带来了一场有关前沿技术和优秀案例的线上盛会。在11月18日的游戏专场中,Unity大中华区技术总监张黎明为广大开发者详细介绍了Unity引擎的详细信息,性能优化以及企业服务。

以下是原视频:

以下是演讲实录:

张黎明:大家好,我是今晚主题演讲嘉宾Unity张黎明。我在Unity中国是负责企业技术支持以及解决方案这方面的工作。今天给大家分享的题目是Unity性能优化以及企业服务。性能优化对于所有游戏的开发者来说是一个千古不变的话题,过去几乎每一年Unite大会上我们都会有类似的主题分享性能方面的经验。

今天的内容和过去有类似的地方,也是先介绍一下我们过去做性能优化常见优化的流程。这次的分享最大的区别是我会在这里介绍我们不久前刚推出UPR线上的性能优化和服务平台。最后我会给大家介绍我们面向中国客户提供企业支持服务的内容。

这里简单先说一下我们为客户提供的一种性能优化服务内容,我们叫做Project Review。简单介绍来说,我们会有Unity官方技术专家来到客户现场做性能分析的服务。第二部分就是讲我们现在一个自动化的线上性能分析的平台UPR,最后是企业服务。

首先看一下什么是Project Review。Project Review过去主要是针对上线前的游戏经常会遇到各种卡顿,帧率低或者是游戏体验不好甚至是崩溃的情况,我们提供了现场支持的服务。我们Unity官方的专家会到客户办公室现场使用各种工具来分析他们的工程,然后找到这个游戏的性能瓶颈,在两天结束之后,我们会写一个完整的性能优化报告,通过文档的形式交给客户,告诉他们游戏里面存在哪些瓶颈,通过哪些方向的改进可以解决这些瓶颈。

在Project Review的流程之前我们先有一个项目沟通的阶段,我们会提前问一下客户这是什么类型的游戏,团队的规模,团队成员的游戏开发经验是怎样的,以及目前已知的性能问题可能有哪些,这样会帮助我们减少一些现场所花的时间。

沟通完之后,我们会预约一个时间,让我们工程师到现场,主要是做以下的这么几部分工作:

首先,我们会有差不多半天的时间去做资源检查。因为常见的一些性能问题经常是因为美术资源的导入设置得不合理,从而导致各种各样的性能的问题。我们会在Unity Editor里面通过人工的方式检查各种资源的导入设置有没有不合理的地方,然后会把它写到文档里面。

后面我会介绍我们线上的性能优化服务,这个工具是怎么样解决我们过去很多人工繁琐的工作。

当然第一部分还是先介绍我们人工是怎么做的。除了做资源检查以外,我们一般在第一天的下午就开始使用Unity工具来做性能分析,其中主要是会用Unity Editor里面自带的Unity Profiler以及Memory Profiler做各种CPU、内存的性能分析。第二天是我们会用一些第三方的工具,最常用的是苹果Xcode里面的Instrument,后面我也会详细地介绍一下这些工具各自的特点。

我们在做Project Review的时候常见的问题,最常见的首先是美术资源。如果美术资源制作的不合理或者是在Unity里面设置的参数不合理,就需要通过人工或者辅助工具进行检查。另外,我们经常遇到有可能CPU耗时过高导致的卡顿,比如加载一个资源的时候,这个资源比较大,有可能导致整个游戏有一定的卡顿。

如果GPU耗时比较多,经常会导致整个游戏的帧率下降,整个游戏运行不流畅。

另外,比较常见的就是gc allocate如果使用得比较多,就会经常导致GC的垃圾回收导致的卡顿。另外,可能还会有内存泄露等等各方面的问题。

所以说我们后面就会用一系列的工具在Project Review里面解决这些问题。首先导入设置的话我们基本上要把常见的美术资源全部做完整的检查,比如说模型的导入设置,贴图的导入设置,音频的导入设置和动画的导入设置等等。但是因为现在游戏的工程越来越大,我们在Project Review里很难做到对所有的资源进行完整的检查。所以我们后面才会在UPR线上的性能分析工具里面提供一些自动化的方案。

做完了资源的检查之后,我们开始用Unity官方自带的Profiler工具先进行分析。Unity Profiler最常见的使用的场景是用它来分析游戏里面的卡顿,你在玩的时候有一帧很卡的话,你可以在Profiler里面找到这一帧,一般它会有一个峰值,我找到它的峰值就可以看到这一帧之内所有函数的消耗,从高到低做排序,我们就可以检查哪个函数导致的耗时过高,然后去优化这一部分。

另外,Unity Profiler常见的一个应用场景是在这里面检查GC的allocate,就看mono堆内存有哪些分配,如果分配过多的话就要优化它,避免mono内存回收的卡顿。

Memory Profiler是用来优化内存整体消耗的,因为这个工具可以图形化地展示你的内存在哪些模块内分配的,是一个render texture,还是普通的纹理,还是UI,还是其他的一些元素分配的,非常清晰地可以看到你的内存分配的布局。

那使用Unity官方工具分析完之后,我们一般都还要用第三方的工具,最主要用的是苹果的Instrument,因为很多性能数据都是在比较硬件底层的,在引擎这一层有些数据是我们很难拿到的,比如说GPU的一些详细的消耗数据往往都是需要通过操作系统或者是硬件厂商来提供的工具进行分析。

Instrument里面最常用工具有三个,第一个工具是Time Profiler,是用来做CPU性能的分析。Time Profiler它相对于Unity的Profiler比较方便的一点是Unity Profiler里面一般只能看到一帧的消耗,它没有办法做一段时间内消耗的统计。Time Profiler里面有一个比较好用的功能就是可以选择一个时间范围,它可以统计这段时间范围内所有函数消耗的排序。后面也会讲到我们在UPR里面实现了一个替代的方案。

另外,Instrument里面的Allocation是主要做内存消耗分析的。它一个最常见的用途是用来检测内存泄露。它的主要功能是你可以看到在一段时间内有哪些内存分配出来但是没有释放掉。如果我从一个主菜单场景进入到战斗场景,再回到主菜单,发现有些内存没有泄露,那这些内存很有可能是泄露的。所以后面我就可以重点地看这些没有释放的内存它们具体是哪里的内存,来确定它是不是泄露,如果是泄露的话,就可以确定怎么解决这个内存泄露。

另外一个常用的功能就是XCode里面抓帧的功能。因为我们要做GPU性能分析,经常是需要抓当前渲染的一帧来看它的每个drawcall的耗时,或者是看所有shader耗时的排序,甚至是看一个shader里面某一个指令的耗时是多少,这在XCode里面都有非常清晰的数据可以展示出来。这些数据其实在Unity Profiler里面是不能提供的。

刚才提到的苹果的XCode里面的功能相对是比较完善的,在一个工具里面,基本上提供了你所需要的常用的功能,但是对安卓平台来说相对复杂一些,因为安卓它的硬件以及操作系统都有一些碎片化。所以说如果我们在安卓上做GPU的性能分析,如果是高通的芯片就需要使用高通的Profiler,如果是用ARM Mali的芯片,就需要用Mali的GPU的Profiler。

另外,像Google的安卓Studio和RenderDoc也是比较常用的分析工具。现在是可以看到我们过去在面向企业客户提供的这些性能服务里面是要使用大量的性能分析工具。对我们的开发者来说,如果大家想自己去做这种性能分析的话,其实它有很大的痛点,因为这个需要使用的工具数量太多,种类太多,对开发者来说是需要消耗大量的时间去学习这些工具的使用方法。而且对这些工具里面所有的数据都需要有一个深入的理解。所以说为了解决刚才提到的这些痛点,我们在不久前推出了一个叫做UPR的线上的性能分析服务。

它的核心还是基于Unity的Profiler的数据,通过我们UPR的工具,我们是可以把你们游戏里面测试的过程中的产生的数据同步发送到我们UPR服务器上面,然后在我们UPR的云端进行性能数据的分析,然后通过可视化的方式把它展示出来。

这里主要是介绍了我们UPR的一些优点,它相对于过去Unity Editor里面的Profiler以及那些第三方的工具有哪些优点。首先它是一站式的工具套件,过去我们在做Project Review的时候,我们要使用各种各样的工具,要不停地在各种工具之间进行切换。现在我们如果用UPR,基本上只需要用这一个工具就能满足你性能优化80%-90%的需求。可能只有很少的功能需要使用第三方的工具进行分析。

UPR里面集成了Unity Profiler的性能分析功能,并对它的数据展示进行了增强。另外,它提供了更多的功能。我们在这里分成了两类,一类是运行时性能数据的分析,另外一类是静态资源的分析。运行时数据包含了Unity Profiler和Memory Profiler,以及对象快照的抓取,我们在不同时间点可以抓取对象的快照做比较,看看有哪些对象创建出来没有释放,就有可能是内存泄露,这个功能可以作为XCode里面Allocation的替代功能。

另外,过去的Unity Profiler里面并没有提供Lua的性能分析,我们在UPR里面也是提供了完整的Lua的性能分析功能。针对GPU方面,我们对RenderDoc进行了简单的集成,你在使用UPR进行测试的过程中是可以在一些时间点抓取RenderDoc的数据,我们会把这个数据保存到UPR的服务器上,当你在后面检查这些性能报告的时候,可以在我们服务器上下载这些当时抓的RenderDoc的数据,然后再用RenderDoc的工具打开这个文件,然后进行渲染方面的分析。

除了运行时的性能数据分析以外,我们还有静态资源检测,包括刚才提到Project Review里面去做大量的资源导入的设置,我们现在提供了一个资源检测工具,可以自动扫描你工程里所有的美术资源,来检测哪些资源它的设置不合理。

另外,我们这个方案还有一个优点,过去有一些第三方提供的方案是作为Unity Editor的插件,需要用Editor打开工程做完所有的资源导入再去扫描,整个流程会非常慢,如果工程复杂的话可能需要几个小时。我们现在提供的这个工具是一个脱离了Unity Editor环境的独立的EXE,非常快速,大概几分钟之内就能扫描完一个非常庞大的工程。

除了这个资源导入的设置以外,我们还有AssetBundle资源冗余的检查工具以及静态代码分析、粒子系统分析等等一些功能,后面还会有一些简单的介绍。

UPR还有一个特点,我们的数据是非常全面的,它除了运行时收集的Unity Profiler数据之外,它会有内存快照和硬件方面的数据,GPU可以抓RenderDoc,另外我们也集成了ARM开源的GPU SDK可以抓取硬件层的GPU的数据。它有Lua性能分析和屏幕截图等等的功能。所以,它的功能完整性是远远要超过过去Unity Profiler里面的功能以及XCode里面的功能。

我们刚才提到了所有的功能的数据展示都是可以在一个统一的时间轴里面,这样会非常方便大家检查某一个时间点的性能卡顿问题的时候非常方便地对比,查找问题在哪个模块里面。

我们所有运行时的数据和静态资源检测数据都是整合在一起,非常方便大家统一地查看性能报告。

UPR还有一个特点,使用起来非常方便,而且我们是对客户的数据安全性非常重视的。

首先我们在做性能测试的时候是不需要用ROOT过的手机,普通手机就可以。我们不需要对你的游戏工程做任何的修改,普通一个Unity的工程只要是发布成development版本就可以使用Unity UPR进行测试。

我们也不需要你上传工程文件或者是你build出来的游戏的APK包、安装包之类的,因为大部分的游戏在上线之前对保密的要求非常高。 游戏测试人员在我们UPR官网上只需要几分钟时间配置你的工程的信息就可以进行测试。

测试之后我们报告的生成也非常快速。因为我们对UPR的报告分析做了好几轮的优化,即使你测几个小时的性能数据,我们几分钟之内就能生成一个完整的报告出来。

另外就是UPR的报表展示是非常强大的,因为我们使用了一些非常先进的数据可视化的工具进行展示,提供了各种可以交互式的可视化展示的方式,里面很多图表是可以进行操作的,可以展开再进入里面看更加细节的数据。

我们现在正在做的工作是在我们最终做的报告里面增加更多专家的建议,因为性能分析的过程是把数据进行数据的可视化,但是看到这些数据之后应该怎么进行优化仍然是一个问题。一般是要通过过去人工的经验总结来得到。

现在Unity在中国技术支持团队比较庞大了,现在程序方向的工程师有大概40人,技术美术大概有10几人。所以,我们这些官方的工程师在过去很多年总结了非常多的经验,我们会把这些性能优化的经验逐步地增加到我们UPR的报告里面,这样大家看到一个报告的时候,里面会自动包含一些优化的建议,这样你就可以知道怎么样快速地修改你的工程,去解决这些性能的问题。

我们UPR过去很长一段时间都在解决稳定性的问题以及生成分析报告性能问题。现在我们经常会看到很多客户使用UPR跑一个游戏几个小时,甚至十几个小时,过去如果不做这个性能优化,其实基本上做不到,可能跑半个小时的数据服务器上就要分析好久才能生成报告。现在十几个小时的游戏测试完,我们都可以非常快的生成数据报告。

我们整个测试的过程是一边测试一边把数据进行上传,所以说基本上没有等待,等你整个测试完成之后大概很快几分钟的时间就能看到一个完整的报告。

除了刚才提到的功能,我们面向重度的游戏现在是提供了一个非常好的功能,就是自动化的性能分析的流程。过去大家常用的性能优化流程,基本上都是在游戏上线之前可能才会做一些性能优化。现在游戏开发周期越来越久,经常需要开发两年、三年。当你性能问题积累得越来越多,到上线之前有的时候会发现有些问题虽然我们知道,但是想去改已经不可能了,因为它牵扯的游戏里面的模块太多,工作量太大,导致不能去修改。

我们未来推荐的性能分析的方式是尽量在每日开发的过程中都进行测试。因为现在大部分的游戏团队有自己的CI持续集成系统,每天都会出一个版本。现在我们UPR是支持接入到你们CI系统里面,等你们每日的版本出来以后可以调用我们UPR的open API,把你们build出来的包发到一个自动化测试服务器上进行测试,测试之后我们UPR服务器会自动生成报告。每天生成的报告我们UPR有功能对比不同时间的性能数据的差别,你就知道如果某一天性能下降了就要检查一下这一天是做了哪些美术修改或者是哪些程序代码修改导致的性能的问题,这样就非常方便地大家查找性能问题的来源。

这里再简单介绍一下几种静态检测的功能。其中第一个刚才已经介绍过了,主要是资源导入的设置。第二个是Asset Bundle ,做Asset Bundle里面冗余性的检查,有哪些资源是不是被重复地打包到不同的Asset Bundle里面。这个工具我们相对一些第三方的工具主要的特点是不需要上传你的Asset Bundle到我们的云端服务器上,而是我们提供了一个工具到你本地进行扫描,扫描之后把这个结果上传到我们UPR的服务器上。

另外,静态代码检测我们是集成了Unity国外团队开发的一个功能叫做Project Auditer功能,它可以做C#代码的静态分析,可以看到有哪些代码写得不规范,有性能问题。

我们静态检查是有哪些优势呢?首先我们刚才提到所有的静态检测的功能都是支持所有Unity版本,是全版本支持的。另外,它也不需要依赖Unity Editor,都是独立的EXE,扫描过程也非常快。它不需要上传你工程的任何文件,都是在本地进行扫描,把扫描的结果进行上传。另外,所有这些工具也不需要安装,都是绿色程序,最终输出的结果是一个结构化的数据结构,如果需要的话,我们面向企业客户也是可以提供原始数据,让你们可以用自己的工具进行分析。

另外,我们UPR是个全平台的分析工具,虽然说现在国内的开发者大部分是开发手机平台的游戏,但是我们这个工具是支持所有Unity Profiler支持的平台,包括移动平台、VR、AR、主机平台、Win等等的所有平台都支持。

除了刚才自动化的这些分析功能以外,我们现在还提供了人工的专家服务,如果你在生成报告之后有一些数据希望得到Unity官方的解读,我们是可以提供人工的服务来帮你们解读这些问题。

刚才我已经提到过UPR是可以面向企业客户提供一些定制服务的。首先,我们可以提供内网的私有云的部署,因为现在有一些企业公司会在内网开发,就是你的开发可能连不到外网。其次,很多公司对游戏数据的保密性要求非常高,我们可以把UPR整个云端的服务部署在你私有的硬件上面。

另外,我们也可以根据你的需求在现在UPR功能的基础上做一些定制化的开发,增加或者是修改一些功能。我们也可以为你们提供真人真机测试,如果你们的测试团队感觉需要花太多的时间去学习UPR,成本太高,我们是可以有Unity官方的测试人员帮你做整个的测试过程。最后,刚才也提到了我们会有远程的报告解读,Unity官方的专家帮你解读你的报告。

这里是我们UPR相关资源的链接,可以查看相关的文档或者是相关的工具。

目前我们UPR支持的主要方式是QQ群,大家感兴趣是可以扫描这个二维码加入到我们群里做一些问题的咨询,我们有官方的技术人员在里面提供问题的解读。

最后再介绍一下我们技术支持团队现在在国内提供的服务的内容。现在我们在国内提供的技术支持主要覆盖了三方面的内容。

过去我们是比较基础地提供一些技术支持、问题解答、bug修复等等,最近这几年国内开发者开发的游戏越来越复杂,会有更加深度的需求,我们现在已经开始提供了引擎定制的服务,如果现有引擎里面有一些功能不能满足你们的需要,我们官方可以提供引擎的定制,开发为你们专门定制的引擎版本,来帮助你们实现你们想要的功能。

另外,我们也有技术美术的团队来提供技术美术方面的支持。这部分我们接下来会有技术美术团队的负责人来介绍技术美术服务的内容,我这里就不详细地介绍。

我先简单介绍几个我们已经定制方案的案例。首先我会介绍一下开放世界的解决方案,后面会介绍一个分布式开发流程加速的方案。我们也会提供类似于卡通渲染的整体的解决方案或者是其他你们需要的功能,我们也是可以根据你的需要进行定制开发。

首先,这是我们开发中的一个开放世界的demo,现在可以看一下这个视频。这个世界大概现在是有4×4公里的面积,里面会有大量的山川、树木、草,各种元素在里面。过去在Unity的老版本里面如果我们要做这么大的开放世界,经常会遇到很多问题。其中一个问题就是LOD的问题,过去Unity里面自带的LOD的最大的问题会导致每个对象、每一级的LOD的mesh都会加载到内存里面,它没有streaming的过程,就会导致你整个场景内存消耗非常大,我们在开放世界方案里面提供了一个streaming的方案,一会儿会介绍。

另外,在开发一个开放世界的游戏还遇到植被的问题,因为它里面有大量的植被。在过去Unity的引擎里面渲染大量的植被会发现相机的裁减剔除、LOD的计算上会花大量的时间。

我们开放世界解决方案主要包括了几个方面的内容,首先我们开发了一个HLOD的系统,是一个分层级的LOD。过去的LOD是针对每一个对象来使用的LOD系统。HLOD是针对整个场景进行了四叉树的切分,切分之后,我们会把低级别的模型进行预先地合并,切成很多块之后,每一块之内低级别的LOD模型会合并成一个mesh,这样离得比较远的时候可以通过一个drawcall就把很多物体渲染出来。

HLOD还解决了一个问题就是streaming,我们可以解决角色在行走的时候动态地判断我当前渲染的高级别的LOD mesh把它加载进来,远处只加载低级别的LOD,这样的话可以动态地加载、卸载,来减少整体的内存消耗。

我们这个方案里面也提供了体素化ShadowMap这种阴影的解决方案,主要是面向开放世界是可以做到几公里范围内都有阴影的效果,过去如果是用CSM的ShadowMap,如果是做几百米,很多硬件性能上就已经吃不消了。

另外,刚才提到了对大量植被的渲染我们主要提供了GPU的加速方案。我们会通过Computer Shader来优化这个相机的剔除操作以及LOD的计算。

分布式方案主要解决了一个问题,现在大家用Unity开发重度游戏越来越多,经常遇到一个问题,一台电脑需要打开一个新的工程的时候会有一个非常漫长的导入的阶段,现在我们提供了一个方案可以用十几台或者是二十几台电脑并行地导入你的游戏工程,过去可能需要导入10个小时才能完成的工程,现在我们使用十几台电脑有可能一个小时就能导入完成。

另外,过去开发过程中还有几个非常耗时的阶段,包括Asset Bundle打包,IL2Cpp代码的编译等等的都非常耗时,我们分别把这些阶段都做成了分布式的加速方案,通过很多台电脑进行并行地处理,来减少处理的时间。

刚才介绍了我们解决方案的内容,再接下来介绍我们常规技术服务支持的内容。

首先,我们传统的技术服务支持主要是通过线上的问题解答,我们使用了一个Zendesk的平台,每个公司会有一个独立的空间来保护信息的保密性、安全性,不同的公司之间是不能看到其他公司的问题。我们会在这个平台上有官方的专家及时地响应你的问题,并进行解答。

除了线上的解答,我们每个月会提供2天的现场的驻场支持。还有一个大家经常遇到的需求就是很多游戏开发周期比较久,经常是开发2年、3年才能开发完,这个过程中你的Unity版本已经不能升级,可能在你上线前又发现了一个bug,在不能升级Unity版本的情况下很多bug没有办法解决,因为Unity很多bug都是在最新的版本里面才进行修复。我们是可以面向企业客户提供这种定制化的bug修复。我们可以在你使用的老版本里面进行专属的bug修复。另外,我们也会提供现场的性能优化分析服务,就是Project Review这种服务。

接下来简单介绍一下我们之前深入支持的案例,就是我们和和腾讯的《Call of Duty》这款游戏手机版进行深入合作的案例。这个项目大概是在前年底、去年初的时间,Unity这边提供了4个官方的专家到腾讯深圳的办公室里面进行驻场服务。

我们4个人大概在深圳办公室待了4个月的时间,前面一两周还是通过各种工具进行性能的分析,分析之后我们会选出来一些性能瓶颈的问题,接下来4个月的时间都是进行引擎的定制,然后给COD这个项目开发一个专有的引擎。

当时我们定制的最主要的内容主要是下面这几个,其中有主线程,渲染线程,OverLap的优化,过去Unity引擎主线程和渲染线程的并行度做得还不够好,我们当时是改了引擎的多线程这部分代码进行优化。

另外就是对相机的剔除计算进行优化,因为这款游戏里面使用了大量的相机,我们怎么样让多线程在很多相机的情况下充分发挥多线程的性能。

我们也改进了JobSystem,主要是在某些手机硬件上多线程job分配的策略其实是需要有不同的策略的。我们也是针对COD这款游戏的特点进行了一些定制。另外,我们也做了Animator的性能优化,主要针对开放世界的需求,游戏里有大量的玩家,近处的玩家可以高频率地更新Animator,远处的角色是可以通过这个功能低频率的更新,这样来实现大量角色同屏动画更新的性能问题。

最后一个功能是Shader Profiler。因为COD这个游戏里面使用了大量的Shader变体。这样就会导致Shader的内存消耗非常大,我们定制了一个Shader Profiler,可以看到每个Shader变体的内存消耗以及每个Shader LOD的内存消耗,这样最终对Shader方面的内存做到了非常深度的优化。

最后这个功能我们现在也在Unity中国版里面加进去了。中国版Unity大部分的开发者应该已经了解,我们在Unity.CN的网站上提供了中国版的下载,主要是针对中国游戏开发者的需求增强了一些功能,其中一个功能就是Shader Profiler,另外还有很多功能大家可以到Unity中文官网上进行查看。

这就是今天我分享的所有内容,谢谢大家。

如若转载,请注明出处:http://www.gamelook.com.cn/2020/11/404918

关注微信