欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~

本文由WeTest质量开放平台团队发表于云+社区专栏

作者:申江涛,腾讯互娱客户端工程师

商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处。

WeTest 导读

加入项目组的这段时间主要是承担性能优化这块的工作,同时也会去实现一些场景材质、特效材质以及工具。今天就性能优化这块分享一下个人的经验。


设备等级划分

设备等级划分是一切优化,LOD策略的前提。

最新的iPhoneX A11 GPU性能直逼笔记本的集成显卡,要照顾三四线的小朋友,红米1你也得想办法支持。

画质选项高中低,游戏第一次启动通过设备硬件配置将设备匹配一个默认画质,匹配依据可以按照CPU,GPU,内存等,也可以根据游戏类型做一些特殊处理,每一档选个代表机器,CPU,GPU性能最好心理有数,可以参考下CPU的天梯1和GPU的天梯2,想拿详细数据的自己写测试案例跑。

默认画质匹配最好是基于配置文件的,这样即使上线后发现匹配规则有问题或者设备更新换代了想优化匹配规则也可以动过热更来刷新。

为满足美术大大们的追求,可以在高画质的基础上再划分一个超高配。

设备等级划分之后,就可以做一些LOD策略了,一定要做的就是划分各种特效的级别,其次场景最好也做一下,有条件的UI元素也做一下,对于非核心信息的UI可以在低配机隐藏。

关于Shader LOD的做法有在这个回答5里面提到,这里就不赘述了。

优化工具

磨刀不误砍柴工,熟练掌握profile工具绝对是打开优化之门的第一步。

Unity Profile


p1.jpg

作为最简单也是最实用的Profiler,即使是不做优化的同学也最好学会如何使用。它能够非常方便地分析出当前的CPU热点。

很多萌新会遇到无法手机连Profiler的问题,如果你也遇到了,请确定下面几个点(假设连Android手机)

1. 手机是开发者模式,且在cmd中输入adb devices能看到自己的设备

2. 配置了Android SDK

3. 编译的是develop build版本

4. Unity当前是Android工程

5. 如果不是在本机构建的,需要在cmd中输入 adb forward tcp:54999 localabstract:Unity-xxxx , xxxx是游戏的包名。

新版本Unity集成了FrameDebugger 和新的内存快照工具,更方便了。

在不开Deep Profile的情况下,看到的消耗比较粗略,很难定位具体的消耗,打开DeepProfile能看到比较深的函数堆栈,但是会有一些消耗,不过在可以接受的范围之内。

移动设备上没法开Deep。

通常遇到的一个问题是手机上的Profile结果和PC上的结果不一致,解决方案如下

一切以移动设备为准,希望详细定位的话可以选择用Profiler.Begin打桩,或者在PC上开Deep Profile找到对应的位置,展开详细的堆栈来定位。

Adreno Profiler


p2.jpg

蛮好用的一个Android平台的GPU Profiler,之前很多人用来提取手游的资源,但是已经被高通抛弃了,已停止更新支持一些老的高通GPU的设备,这边确定好用的是红米 Note 1.

如果能找到可以用的设备可以,建议还是可以连一下看看,还是能看到很多东西的:DC数量,绘制顺序,渲染shader,动态修改shader看效果,贴图格式…

这个东西除了看性能还可以用来查一些平台相关的渲染错误。

XCode


首先你要有台Mac以及不算太老的ios设备。

首先要去Apple 申请一个免费的开发者账号,然后从Unity构建一个Xcode工程,连上真机运行。

p3.jpg

相对于Adreno, Xcode显得专业很多,功能更加强大,最重要的是,可以看渲染耗时!这对于分析GPU热点非常有帮助。

CPU时间显示一直为0,不知道试Unity的bug还是XCode的Bug。

Instrument可以看函数耗时。

备选

--

Mali Graphic Debugger:只能用于Mali的GPU, 看上去很厉害,4.X从来没有连接成功过, Unity5.X的集成稍微友好一些,还没有深入研究。

Snapdragon Profiler:很卡,只能用于高端机,只能用于Android 6.0以上的系统,年底出了新版本,还可以。

Unity Frame Debugger:5.X以上才有,很方便,没详细研究。

WeTest - UPA:和Unity官方合作的客户端性能测试工具,无需ROOT和接入SDK,挺方便。

优化流程

如果想在后期轻松一些,美术的规范一定要定好,同时要有配套的资源检测,扫描工具。在定一些大的技术方案之前,各项消耗尽量做到心理有数,如果不确定就做一些实验,数据不会能骗人。

遇到上线前三天发现游戏只有十几帧的,这就只能砍效果了。

程序ic方面主要是对C#的语言底层机制的熟悉程度以及对数据结构的理解,一些明显有性能问题的写法要规避。

项目上线前两周左右就要开始对版本进行一些性能评估。高中低三档机的帧率,内存,耗电等都需要有数据。接下来就是

发现热点 -> 优化 ->继续发现热点->继续优化 –>继续…

这个过程肯定是没法由优化的人一个人搞定,最好是进行完一轮Profile之后,把需要优化的点记录下来,然后通过tapd等工具将优化任务派给对应的美术/程序同学,并去推进优化迭代,这其实牵涉到很多沟通工作。

关于GC

GC方面的优化很重要,原则就是任何大于20B的GC都值得被注意。GC的优化比较琐碎,也比较考验基本功。

除了最简单的避免使用foreach,避免频繁new内存,ToString。下面几个点可能是往往容易被忽略。

  1. GameObject.SetActive会引起GC

优化方法:对于渲染相关的,可以考虑是否隐藏MeshRenderer来替代,还有就是把GameObject拉到很远的地方,UI也同样适用。

  1. C#自带的排序有GC

优化方法:自己实现排序算法,数量不多的直接写个简单的冒泡就行。

  1. 反射会引起GC

优化方法:大部分的反射都可以用dictionary做缓存。

  1. List.Add会有GC

优化方法:List底层是数组,在数组容量不够的时候就会扩充,会产生GC。可以考虑在new的时候直接指定大小。

  1. Box Unbox 会有gc

Boxing的GC很隐藏,打桩也很难发现,Boxing的触发条件:当需要将栈(Stack)上的值类型转换为堆(Heap)上的引用类型,这个过程被称为“装箱”,它具有以下特性:

  1. 在堆(Heap)上分配空间
  2. 通知垃圾回收器有关新对象的信息
  3. 复制值类型对象中的数据并传递给新的引用类型对象

当初是发现了Behavic组件底层有GC,跟到很下面的时候发现是一个equal函数

里面有一处改动是这样。

p4.png

GPU优化

不说GPU占有率,直接说GPU耗时Xms就是耍流氓。

通常XCode里面有GPU时间,对于一个30fps得游戏,理论上GPU有33ms的时间可以用,但是这个时间超过20ms的时候,就会发现再往上增加一些渲染消耗(1,2ms左右),GPU耗时不会明显增加,而原有的一些渲染消耗可能要1.5ms的你会发现只要1ms就可以了,这个时候其实GPU负载已经有点过了,GPU为了流畅度开始提升频率(iPhone 6 plus亲测)

p5.png

GPU的优化其实就是和美术同学Battle的过程,找到那个平衡点,就算优化成功了。很多时候GPU的优化不仅仅是Profile看热点,而是需要你给出方案,这就很看经验了,萌新需要多问问老司机。

下面几个点一定要注意!

Overdraw! Overdraw! Overdraw!注意每一块半透明是否需要渲染,面积是否能够减少。

Shader的复杂度会影响fillrate。

游戏场景内最好不要出现alpha test,会影响Hidden Surface Removal(HSR)的处理。

不要轻易尝试后处理,耗CPU, 耗内存, 耗GPU,中低配一定要关掉。

粒子系统请慎重使用,耗CPU,多Overdraw,数量和粒子总数都要控制好。

Static Batch 会消耗内存。

Dynamic Batch耗CPU,但是当需要渲染很多个同样的MeshRenderer的时候,对于减少DC非常有效,建议开启。

单局外的性能也要注意!

耗电优化

当优化完卡顿问题之后,本人就开始想着做一些炫酷的事情了,比如更酷的特效啊,后处理加起来啊,然后对于移动平台来说,你不是不卡就可以了,耗电,发热也是要重点考虑的事情。

耗电的几个大头,GPU,网络,CPU,GPRS,喇叭,屏幕亮度等等。上面介绍了几个Profile CPU, GPU的工具,但是电量怎么Profile呢?

关于耗电的优化踩过很多坑,参考网上能找过的方法挨个试了,比如用ios设备的记录耗电情况日志,或者是XCode的Energy impact等等,统统无效,其中的坑就不一一说了。只说一个绝对有效的方法。

使用WeTest云真机耗电量测试!基于自家的耗电盒子来检测电量,测得的结果精准。

p6.png

还有就是设备一直处于充电状态,和实际使用有偏差,不过都在可接受范围内。

首先要测试出一个同品类游戏或者标杆产品的耗电水平,比如测得王者5v5单局得耗电如下:

p7.png

接下来就可以测自己得apk了,测试得时候,最好可以通过作弊指令去动态开启关闭一些特性,得到各项的消耗,想要测得比较精确的结果就多次测取平均。

得到各项的消耗之后,就可以有针对性的优化了。

数据上报统计

数据上报统计是指将玩家的设备信息,设备画质选择,帧率信息进行上报,这样每次测试都能获取到很多有用的信息,利用这些信息可以进行相应的调整,比如说某些默认画质匹配占比,不同设备的性能表现,各类硬件的占比,比较卡顿的场景有哪些等等,同时也可以横向对比看优化的效果。

小结

记得刚加入团队,飞车刚好要进行第一次轻度测试,那次测试的收到很多的玩家抱怨各种卡顿,竞速赛卡,道具赛卡,连我们的策划同学在跑单人单局的也觉得卡…当时为了保证流畅把大部分的机器归为了低配机,还有很多玩家,设备是中高配的,为了开上高帧率,将画质设为低…..

到PR2的时候,经过一轮强力优化,也是和美术策划同学的通力合作,将默认中高配的设备从20%多提升到了70%以上,对于低配机,我们尽量会满足30fps流畅运行,对于中高配,60帧的顺畅体验可以让他们觉得玩的是另一个游戏(Android设备需要开始多线程渲染),如今正式上线,在TapTap这种黑腾讯游戏即政治正确的社区,好评也是绝大多数。

不过还是会有一些没有优化到的地方,比如

”Android 机开局的完美起步会卡啊!“

“-请期待年前的版本”

”休闲区还是很卡啊!“

“-请期待年前的版本”

”新手引导品质太低了吧!“

“-请期待年前的版本”

….

优化是件漫长的事情,因为总有可以优化的东西,这里的面是不是可以更省,那边shader精度减一下是不是可以…..自身也需要去掌握多种的profile技术,内功也要加强修炼才行,你拿着消耗去和美术大佬谈判,总得给个靠谱的解决方案吧。

对于一个老司机,应该在项目之初就能够把各个标准都定好,给出最好的解决方案,能做的不能做的都和大佬拍好,这样后面就舒服一些,但大部分还是一边现问题一边处理,然后慢慢地把规范和自动化测试流程搭建起来,这样也不失为亡羊补牢,这里面其实又涉及了一些TA工作。

特别感谢在优化过程中能够耐心给我解答问题的各位前辈,非常感谢!

篇幅原因,能覆盖的就这些了,没有涉及到的或者有误的迎大家指正。

参考

1 手机CPU性能天梯图

2 Smartphone and Tablet Graphics Cards - Benchmark List and Comparison

3 mobile cpu上禁用alpha test的相关总结

4 iOS Hardware Guide

5 Unity移动开发如何依据性能选择shader? - 拳四郎的回答 - 知乎

问答
游戏体系结构
相关阅读
团战开黑必备“良药”了解一下!
再也不用担心网吧开黑队友听不清了!
3行代码,为QQ轻游戏加上语音互动能力
【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识

此文已由作者授权腾讯云+社区发布,更多原文请点击

搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!

海量技术实践经验,尽在云加社区

七个要素帮你打造现象级手游!优化程度堪比《QQ飞车》的更多相关文章

  1. 腾讯首度公开S级手游品质管理方法

    weimjsam   引言 在最新的手游市场占有率统计中,腾讯游戏稳稳占据一半江山,目前仍以每月一到两款的速度推出新品,在如此复杂多变.响应要求极高的市场环境下,能持续推出高质量产品并保持高效迭代更新 ...

  2. Unity手游之路<七>角色控制器

    Unity手游之路<七>角色控制器 我们要控制角色的移动,可以全部细节都由自己来实现.控制角色模型的移动,同时移动摄影机,改变视角.当然Unity也提供了一些组件,可以让我们做更少的工作, ...

  3. MySQL千万级大表优化解决方案

    MySQL千万级大表优化解决方案 非原创,纯属记录一下. 背景 无意间看到了这篇文章,作者写的很棒,于是乎,本人自私一把,把干货保存下来.:-) 问题概述 使用阿里云rds for MySQL数据库( ...

  4. APP内计费规范出台 手游乱收费现象能被遏制?

    手游乱收费现象能被遏制?" title="APP内计费规范出台 手游乱收费现象能被遏制?"> 在一个混乱.无秩序的环境中竞争,虽然有可能不择手段地获取更多的利益,但 ...

  5. 10款优秀Vim插件帮你打造完美IDE

    导读 如果你稍微写过一点代码,就能知道“集成开发环境”(IDE)是多么的便利.不管是Java.C还是Python,当IDE会帮你检查语法.后台编译,或者自动导入你需要的库时,写代码就变得容易许多.另外 ...

  6. 现象级AR营销助力“口碑双十二”,蚂蚁特工在全国数万商户掀起“AR捉四宝”

    领取阅读奖励金 今年双十二,全国人民吃喝玩乐放飞自我,嗨出了新纪元.除了见证你国人民的财力,这个“双十二”还诞生了教科书级的“AR营销”.无论是在口碑商户门口,还是在各大购物广场,都能看到举着手机,正 ...

  7. 【转】七个例子帮你更好地理解 CPU 缓存

    我的大多数读者都知道缓存是一种快速.小型.存储最近已访问的内存的地方.这个描述相当准确,但是深入处理器缓存如何工作的"枯燥"细节,会对尝试理解程序性能有很大帮助. 在这篇博文中,我 ...

  8. 如何打造千万级Feed流系统

    from:https://www.cnblogs.com/taozi32/p/9711413.html 在互联网领域,尤其现在的移动互联网时代,Feed流产品是非常常见的,比如我们每天都会用到的朋友圈 ...

  9. 用guava快速打造两级缓存能力

    首先,咱们都有一共识,即可以使用缓存来提升系统的访问速度! 现如今,分布式缓存这么强大,所以,大部分时候,我们可能都不会去关注本地缓存了! 而在一起高并发的场景,如果我们一味使用nosql式的缓存,如 ...

随机推荐

  1. Vue以CDN方式调用Swiper轮播异常

    问题概览: 有一个小型单页应用项目,嫌用组件式调用vue-swiper麻烦,因此以CDN的方式调用swiper,结果轮播的图不动了! 爬了半天百度和谷歌都无解决方案,最后曲线救国的方式解决了问题. 解 ...

  2. Windows 下的文件被占用问题解决

    windows下,经常容易出现文件被其他程序占用的现象,令人十分头疼.更头疼的是,还看不到被谁占用. 实际上是有办法看到占用的进程的. 话不多说,以Win10为例: 1.打开资源监视器 a.直接程序栏 ...

  3. django模板系统(下)

    主要内容:母版,继承母版,块,组件,静态文件 母版 <!DOCTYPE html> <html lang="en"> <head> <me ...

  4. COM动态添加删除成员,类似JavaScript中调用的对象

    在JavaScript中调用对象时,可动态添加删除成员如: var obj=new Object; obj.member1='aaaaa'; obj.fun1=function() { alert(' ...

  5. sql点滴44—mysql忘记root密码

    1. 首先检查mysql服务是否启动,若已启动则先将其停止服务,可在开始菜单的运行,使用命令: net stop mysql 打开第一个cmd1窗口,切换到mysql的bin目录,运行命令: mysq ...

  6. Gitkraken的使用

    一个优秀的团队合作离不开git,一个优秀的程序员也离不开git.gitkraken是我在进行软工实践这门课接触到的git的UI界面的工具,它给我留下的印象就是非常好用和方便 怎么个方便法呢? 方便的安 ...

  7. 【Alpha 冲刺】 10/12

    今日任务总结 人员 今日原定任务 完成情况 遇到问题 贡献值 胡武成 完成app端api编写 未完成 Json格式出了点问题,修复中 孙浩楷 图片在线编辑器插件引入 未完成 耦合了,结果另外一个那边做 ...

  8. Java BAT大型公司面试必考技能视频-1.HashMap源码分析与实现

    视频通过以下四个方面介绍了HASHMAP的内容 一. 什么是HashMap Hash散列将一个任意的长度通过某种算法(Hash函数算法)转换成一个固定的值. MAP:地图 x,y 存储 总结:通过HA ...

  9. 关于datatables与jquerUI版本冲突问题

    今天开发项目是,需要用到表格,于是想到,之前的项目中使用过datatables插件,于是就拿了过来,但是发现无法识别 Uncaught TypeError: $(...).DataTable is n ...

  10. oracle 更新用户密码,授连接权限,

    1.授连接权限 grant connect to 用户名; ALTER USER 用户名 ACCOUNT UNLOCK; 2.更新密码 ALTER USER 用户名 IDENTIFIED BY 更新密 ...