Unity 性能调优技术集锦

性能调优,一直是游戏上线之前的很重要的一个环节, 游戏帧率过低,手机发烫, 低端机上跑不起来等, 这些都需要来做优化,今天我们来给大家分享Unity做性能调优的指导思想与解决方案。

这里有个unity学习交流小组点击可以直接加入,一起学习交流吧

性能调优的指导思想

接触过很多刚做性能调优的小伙伴,他们做性能调优最大的问题一开始就通过猜测,推断来做性能调优,缺乏一个做性能优化的系统指导流程, 导致优化的效果不好。性能调优首先要分析问题,定位问题,证明是这块有问题后再对症下药,着手优化,拿出解决对策。没有证明问题之前,不要随便动手优化,就像医生,看病做手术前先做检查。不确定问题就随便开刀,那是极不负责任的做法。

大家可以回想一下,当帧率低的时候,你马上就是去查Drawcall,去优化降低Drawcall,这里我想说,做性能优化之前,先定位,证明确实是Drawcall的问题导致性能下降,才动手。如何来定位问题,找出引起问题的代码或物体呢?接下来给大家介绍一些方法。

(1)对比法

例如, 刚开始的时候帧率是60FPS,同一个场景运行一段时间以后是30FPS,如何优化,像这种符合很明显的对比场景,我们可以通过前后对比,来找出60FPS,30FPS,最大的变化。一般可以通过打开stats, 来观察前后主要的变化,main thread耗时,render thread耗时, 三角形面数,内存等信息,看看前后明显发生的变化。看到数据变化以后,再来思考整个过程中代码做了哪些事情,出现过哪些物体,最可能出的问题的地方,然后再证明, 只有证明了问题的存在,再着手优化。

(2)隔离法

这个是我经常用的一个方法, 就是隔离可疑区域和代码,然后比较,逐步排查,缩小问题范围。隔离法其实是非常好的方法,看上去很笨,很慢,但其实效率远比你想像的要好。比如,场景的物体过多,这个问题,那么我就可以采取隔离方法,先减少掉一倍,看效果。某个代码引发了帧率下降,可以逐步的注释掉代码,来观察结果,隔离的时候,可以采用二分查找,一半一半的排查。排查范围很快被缩小,问题也就精确的定位了。

(3)反经验法

上面介绍了常用的两种方法,定位问题,还有其他的一些方法,但我更想说的就是反经验法。你没看错,反经验,在性能优化的时候,不要过分相信经验,一步一步的逐步分析,有条不稳。不管什么问题,按部就班,不要根据经验,武断的下结论,要严格证明问题所在后再动手, 很多小伙伴遇到性能问题后,把问题简单的描述一下,去请教一个经验丰富的人,问他可能是哪方面的问题,根据他的猜测,你来优化。这种方式是很难做好你项目的性能优化的,项目和项目都不一样,连具体的问题都没有定位,你去请教经验丰富的老者,从老者的角度来说也无法帮到你。不要迷信经验,在动手前一定要定位好谁的问题,然后才能针对具体问题下对策。

优化架构, 标准规范化开发流程

好的框架设计,不仅让大家能很好的在一起工作,同时更方便我们快速的反应和定位问题。你的项目不好定位问题,那么一定是框架设计做的不好。所以开始做项目的时候,框架设计要花点时间,模块尽可能的独立,模块入口尽量清晰,整个框架设计能很好的隔离错误的蔓延。资源视图与逻辑代码分离,游戏数据与代码逻辑分离。这些都有助于快速的定位问题,比如我要验证是否物体过多,导致性能问题,只要在表格上配置一下,少放一些物体就可以验证,如果觉得是某个功能,导致消耗CPU,可以把物体的这个功能的组件关闭或不添加,比如怀疑怪物AI,可以注释掉添加怪物AI的组件,来证明。好的框架设计,在定位问题的时候,就变得非常简单。如果是ECS,定位会更加简单,内存看Entity与资源,算法性能看System与物体规模……

接下来要给大家介绍的是我认为最重要的经验,就是标准化,规范化项目开发进度和流程, 把性能问题一开始就放到日常项目开发中。我带项目的时候,每个礼拜至少做一次发布版本的测试,包含各个平台,不同的手机等。严格监测性能各项数据,哪个礼拜出现性能问题,马上可以回溯,复盘数据,着手摸清楚并解决,尽快修正。项目立项后,尽快的验证核心玩法极限时的性能开销与测试。不要等游戏项目做完了,才去验证,在设计初期验证完成后,针对一些性能问题组织技术公关,可能还要修改策划需求和玩法, 早期把性能问题尽快越早摸清楚,是确保整个项目成功上线的关键,不要等到上线了才到各平台做测试,那个时候功能多了,不知道有些问题是从什么时候开始就有的。标准的严谨的开发流程,伴随项目监控性能数据,尽快验证核心玩法,提前引入测试, 让我们整个项目开发做到有问题尽早发现,尽早纠正。

Unity 性能优化方法集锦

讲完指导思想,和开发流程这些宏观问题后, 我们再来讨论一些具体问题的常用的优化方法。

(1)包体体积优化:

声音文件优化

将wav,压缩成mp3或ogg, 最好是ogg,没有版权问题, 将多声道变成单声道。改变声音的采样率与码率,减少声音文件体积。

字体文件优化

尽量多使用系统字库,这样不用额外带字体文件。可以使用一些位图字库,来替代额外的字库。如果你的文本内容是固定的,可以对字库进行裁剪,把不用的字从字库里面删除掉,减少自带字库的体积。

贴图文件大小优化

将png转jpg, 并使用图片压缩软件,压缩贴图体积, 尽量减少图片数目,复用图片,尽量能使用颜色等代码的方式来代替贴图。

3D模型文件

根据需求适当降低模型面数, 去掉多余不用的数据, 可以通过法线贴图,高度贴图等将低模做出高模的效果, 合并贴图通道数据(PBR工作流中,将金属度,粗糙度,环境遮挡放一个纹理里面, 将数据合并到贴图不用的通道,比如Albedo贴图,Alpha通道不用,可以存放环境遮挡等,节约贴图数目)。

将资源ab包化

把所有的资源分成一个一个的ab包,ab包本身有压缩功能,这样整体的包体也会减小,如果可能,可以把ab包全部或部分放服务器,第一次运行游戏的时候再下载,比如《王者荣耀》,这样来节省包体体积。

(2): 骨骼动画优化:

3D游戏中骨骼动画也是非常消耗性能的地方,因为每帧,我们都要通过动画组件采样,采样后重新计算出来我们的顶点的位置,传给GPU的渲染管线来处理绘制, 我们可以将骨骼动画的每帧顶点的位置缓存到一个纹理贴图里面,用空间换时间的方式来节约动画组件的开销,并尝试合并Drawcall。

(3): LOD的优化:

对于大规模多角色的场景游戏,我们要开启LOD,让远处的物体用尽量少的面,近处的物体用更多的面, 来提升我们运行时候的性能。

(4): 使用3D模型细节增强,提升计算性能:

使用法线贴图,高度贴图等细节增强手段来降低模型的面数同时,能获得和高模同样的细节和更好的计算性能。

(5): 光照优化:

静态光照烘培+反射探头来做更好的场景效果,代替实时的光照计算,减少光源的数目。对于一些物体的发光特效,可以通过shader来实现,而不用加光源。定制Shader,可以将逐像素光照改为逐顶点光照,节约逐像素光照的计算开销。

6: SetPassCall与Drawcall优化

SetPassCall

SetPassCall通俗的讲就是更换重新装载在渲染管线里面的Shader代码和配置,就像换画笔一样的。SetPassCall开销非常的大,所以尽可能的要少用一些不同的Shader,在一个场景里面。尽可能的让同一个Shader 绘制最多的物体后再切换下一个Shader的物体。尽量避免绘制物体的时频繁交叉的来回切换Shader,节约SetPassCall的次数。

DrawCall

DrawCall 优化,其实很简单, 三种优化手段,静态合批,动态合批,GPU Instancing合批, 然后我们针对合批的条件去达成对应的条件就可以了,比如,我们做一个捕鱼达人3D游戏,我们有很多的鱼,可以把鱼的所有纹理贴图,放到一个大图里面,这样,这些鱼就是同样的Shader,同样的纹理贴图对象,就可以达到合批的条件而做到合批, 节约Drawcall。

(7): 物理引擎的优化:

能不用物理引擎的游戏,尽量不用物理引擎,能自己实现的尽量用代码自己实现,因为物理引擎的开销毕竟摆在那里了, 物理引擎使用很简单,但是性能开销也不可忽视。有一些不是真正的物理游戏,比如Moba类的游戏,防止物体穿透等,其实我们可以不用物理引擎,通过制作地图格子的方式,标记障碍物,自己控制的时候,如果进入障碍物的标记,就不让它更新位置即可,这些可以替换物理引擎获得很好的性能效果。常用的有菱形的地图格子与六边形的地图格子。

暂时不用的刚体,或者不在视线范围内的刚体可以根据游戏的需要,显示和隐藏,达到节约物理引擎计算的目的。修改物理引擎全局的迭代参数,获得实用性的同时又有更好的性能。了解物理碰撞器的性能开销,球体碰撞器最小,网格碰撞器最大,尽量使用开销小的碰撞器, 对于静态物体,能够合并物理碰撞器的尽量用一个物理碰撞器。

(8): 阴影的优化:

通过开关控制阴影,在低端机上关闭阴影获得更好的运行帧率,在高端机上开启阴影,获得更好的运行效果。通过伪阴影技术来做贴图,节约阴影计算的开销, 可以自己定制Shader来实现高性能的阴影效果。

(9): Shader优化:

减少Shader中的条件判断和展开循环,来获得更好的指令缓冲cache 命中率, 减少一些复杂的计算,可以采用一些空间换时间的方法来缓存计算结果。逐顶点计算来替代逐片元的计算,减少计算次数。可以把Shader 设置为常驻内存缓存,这样节约SetPassCall所带来的开销。

10: C#良好编码习惯与算法思想

Update里面尽量不要使用GetComponent, Find等,可以在初始化的时候先找出来,能放Update里, 尽量不放FixedUpdate, 这样低端机上能节约计算次数。全局设定,降低FixedUpdate每秒调用迭代的次数,节约FixedUpdate迭代时的计算时间。避免大量反复的new 对象。一些重复使用的对象,可以通过节点池等先反复使用,避免重复创建与释放。

可以用多线程来做一些计算,避免卡住main thread游戏线程导致帧率下降。不要在游戏主线程里面直接做同步的IO以免卡住游戏线程,导致帧率下降。

从开始写代码起,要把每行代码写好,长期的坚持积累,才能形成良好的代码习惯,写出高性能,高质量,高效率的代码,学好数据结构与算法,能很好的分析算法的时间复杂度,空间复杂度等。

经过上面的一些讨论,可能还会有很多优化技巧,欢迎大家留言讨论。同时我们有很多免费的Unity 性能优化的视频课程,供大家可以学习,成为优化优化的高手,

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容