Unity 性能优化经验整理

优化思路

我的优化原则:
三原则:
注意细节、注意细节、注意细节!html

优化手段:
1.减小总量
2.空间、时间互换
3.由浅入深c#

1.减小总量:
尽可能减小内存和CPU占用的总量。segmentfault

2.空间、时间互换:
内存和CPU能够互换、CPU和GPU能够互换。缓存

3.由浅入深:
先优化小的细节再优化大的结构。性能优化

大体手段:
1.降CPU
2.降内存
3.内存换CPU
4.CPU换内存
5.GPU换CPU
6.磁盘换内存app

优化思路说明:
尽可能减小占用的内存(资源体积)和CPU(计算量),是一切的前提,首先着重减小总量才能更好的进行后续细节的优化。
因为内存比CPU便宜多了,因此通常都是内存换CPU的,内存不够时再用CPU换内存。
好比利用对象池缓存对象,能够省略加载资源、实例化、销毁实例、卸载资源的步骤,能够明显下降CPU的消耗。
利用Loading进度条按需加载资源,能够减小内存峰值,大量节约内存。框架

一般来讲先优化细节,若是细节优化已经作的很好,没什么太多潜力能够挖了,性能仍是消耗太大,那么就须要考虑重构结构了。异步

性能分析:
使用Profiler性能分析器首先肯定性能瓶颈出如今哪里,定位性能问题出现的根本缘由,按照具体缘由去作优化。
一般来讲,性能问题大体出如今两个方面:
1.细节不够好(资源问题、插件问题、代码写法问题)
2.结构不够好(框架问题、底层API问题)性能

细节问题解决成本低,能够独立调整,对其余部分影响小,能够批量解决。
结构问题解决成本高,牵一发动全身,对其余部分影响大,须要大修、大测。
因为游戏总体是由各个细节组成的,因此当细节作的不够好时,总体也会显现出问题。
反之当结构不够好时,细节即便作的很好,游戏总体表现出的性能也不会太好,二者是相辅相成的。
个人建议是:用严格认真的态度控制细节,用丰富的经验积累出可靠的结构。
前者靠态度,后者靠经验。当咱们经验很少时,应该依靠态度严控细节,当咱们经验足够时,两方面都要兼顾。学习

多读官方API:
多读官方API,多读官方API多,读官方API。重要的事情说三遍,不要重复造轮子。Unity中有不少性能细节问题都出如今功能不熟悉上,没玩明白致使的,熟悉官方API可让咱们事半功倍。C#代码也同样,也要熟悉C#官方API。

优化内存

Unity中 资源占用的内存量比代码高的多,只要代码不往死掉写,通常不会占用过高内存,咱们要特别注意资源的内存占用。
Unity资源内存占用排行榜
1.贴图 Textures
2.动画 AnimationClips
3.网格 Meshes
4.音频 AudioClips
5.材质 Materials

资源内存占用说明:

名称 单个体积 同时使用数量 整体内存占用 内存占用说明
贴图 不少 很大 占用超级大户 远超其余资源(超级土豪VIP熟客 需重点关照 利润大)
动画 占用大户 时间越长 关键点越多体积越大(普通顾客 认真对待 利润中)
网格 占用中等 和精细度有关 通常内存问题不会出如今它身上(普通游客 利润小)
音频 占用大 压缩比高 ogg加进内存后 体积增大10倍(土豪游客 出现一次狠宰)
材质 很小 很小 占用很小 数量也少 (邻居 别期望从它身上赚钱了)

1.减小贴图占用内存
内存占用超级大户,史前怪兽级别的,要优化内存先从优化贴图格式开始。
按照下面3步设置,能够极大下降贴图占用内存。
1.下降分辨率
2.拆分透明通道
3.调整压缩格式
4.禁用Mipmap
5.启用Use Crunch Compression

1.下降分辨率(Max Size):

根据Game摄像机距离物体最近时,物体所占的像素大小(QQ截图),来肯定最大分辨率。
通常美工或Asset Store上下载的资源极可能是高清资源,1024x102四、2048x2048或更大,咱们须要根据实际使用的尺寸肯定。
2048x2048下降为1024x1024后 内存会下降为原来的1/4 极大下降内存占用 这里是是大头 要控制好。
(图片大小和像素有关 像素点数=宽x高=面积 宽高各变为1/2 面积变为1/4)

2.拆分透明通道(Alpha):

不须要Alpha通道的必定要去除Alpha通道 由于带Alpha通道的贴图 Unity会默认选择RGBA格式。
若是不能剔除Alpha 要把format由RGBA格式选为RGB格式 以减少内存占用。
非渐变的透明贴图 能够调成RGB + 1bit alpha的格式 拆分alpha通道。
(RGBA通常各通道是平均分 每份1/4 剔除一个通道 体积减小1/4)

3.调整压缩格式(Compression):

尽可能选用当前平台支持的最高压缩格式,不要轻易使用RGBA32格式,更不要使用不压缩格式,内存天差地别。
只要启用Compression选项,Unity会自动帮咱们选用合适的压缩格式 要注意的是压缩格式的支持都是有条件限制的。
当不能使用更好的压缩格式时,Unity会出现提示,告诉咱们哪里有问题。对于压缩格式:通常要注意如下两个问题。
(1)不须要Alpha透明通道的贴图 请在PS里剔除。
(2)高压缩比格式要求图片宽高是2的倍数(4的倍数更好) 宽高不能被2整除,会致使不能用高压缩比的格式。
宽高禁止出现奇数,必须都是偶数,打成图集的图片是2的倍数便可,单独使用的图片宽高要是4的倍数。

以一张512x512分辨率的图片为基准 测试不一样平台 不一样压缩格式占用的内存:

PC经常使用图片格式:DXT

图片格式 512x512(启用Mipmap) 1024x1024(启用Mipmap) 图片质量 内存(压缩比) 说明
RGBA 32 bit 1M(1.3M) 4 M(5.3M) 最高 最大(1) 透明高清无压缩 最靠后选择
ARGB 16 bit 0.5M(0.7M) 2 M(2.7M) 中(1/2) RGBA32阉割版 靠后选择
RGB(A) BC7 256KB(341.4KB) 1M(1.3M) 中高 小(1/4) 透明高清高压缩 次优先选择
RGBA DXT5 256KB(341.4KB) 1M(1.3M) 小(1/4) 透明中清高压缩 最优先选择
RGB 24 bit 0.8M(1M) 3M(4M) 很大(3/4) 不透明高清无压缩 最靠后选择
RGB 16 bit 0.5M(0.7M) 2M(2.7M) 中(1/2) RGB24阉割版 靠后选择
RGB DXT1 128KB(170.7KB) 0.5M(0.7M) 很小(1/8) 不透明中清高压缩 最优先选择

RGB(A) BC7:高质量高压缩格式 可是mac上不兼容

Android经常使用图片格式:ETC

图片格式 512x512(启用Mipmap) 1024x1024(启用Mipmap) 图片质量 内存(压缩比) 说明
RGBA 32 bit 1M(1.3M) 4 MB(5.3M) 最高 最大(1) 透明高清无压缩 最靠后选择
ARGB 16 bit 0.5M(0.7M) 2 MB(2.7M) 中(1/2) RGBA32阉割版 靠后选择
RGBA ETC2 8 bits 256KB(341.4KB) 1 MB(1.3M) 小(1/4) 透明中清高压缩 最优先选择
RGB 24 bit 0.8M(1M) 3M(4M) 很大(3/4) 不透明高清无压缩 最靠后选择
RGB 16 bit 0.5M(0.7M) 2M(2.7M) 中(1/2) RGB24阉割版 靠后选择
RGB ETC2 4 bits 128KB(170.7KB) 0.5M(0.7M) 很小(1/8) 不透明中清高压缩 最优先选择
RGB ETC 4 bits 128KB(170.7KB) 0.5M(0.7M) 很小(1/8) 不透明中清高压缩 次优选择

IOS平台经常使用图片格式:PVRTC

图片格式 512x512(启用Mipmap) 1024x1024(启用Mipmap) 图片质量 内存(压缩比) 说明
RGBA 32 bit 1M(1.3M) 4 MB(5.3M) 最高 最大(1) 透明高清无压缩 最靠后选择
ARGB 16 bit 0.5M(0.7M) 2 MB(2.7M) 中(1/2) RGBA32阉割版 靠后选择
RGBA PVRTC 4 bits 128KB(170.8KB) 0.5M(0.7M) 很小(1/8) 透明低清高压缩 最优先选择
RGBA ASTC 6x6 block 115.6KB(154.7KB) 456.9KB(0.6M) 很小(~1/8) 透明中清高压缩 iPhone6以后首选
RGB 24 bit 0.8M(1M) 3M(4M) 很大(3/4) 不透明高清无压缩 最靠后选择
RGB 16 bit 0.5M(0.7M) 2M(2.7M) 中(1/2) RGB24阉割版 靠后选择
RGB PVRTC 4 bits 128KB(170.8KB) 0.5M(0.7M) 很小(1/8) 不透明低清高压缩 最优先选择
RGB ASTC 6x6 block 115.6KB(154.7KB) 456.9KB(0.6M) 很小(~1/8) 透明中清高压缩 iPhone6以后首选

PVRTC:IOS原生支持的一种压缩格式 优势是:高压缩比 兼容性好 缺点是:有损压缩 图片质量较差,对于透明像素的边缘和渐变的透明度有特别明显的失真。
ASTC :IOS支持的一种新的压缩格式 优势是:比PVRTC更高的压缩比和质量,透明贴图质量更高 缺点是:兼容性差 iPhone6才开始支持该格式,iPhone5和以前不支持该格式。

参考资料:
《干货:Unity游戏开发图片纹理压缩方案》https://www.jianshu.com/p/f7c...
《Unity3D的图片压缩格式详解》https://www.jianshu.com/p/bec...
《Unity3D~纹理格式》https://www.cnblogs.com/rayya...
《Unity中一个简单的图形优化指导》http://gad.qq.com/program/tra...

4.禁用Mipmap

Mipmap至关于Texture的LOD 启用后会生成多级纹理 会占用更多的内存 好处是会让贴图看起来更平滑。
启用该选项会生成多级小贴图 内存会增长1/3。

5.启用Use Crunch Compression

Crunch是Unity支持的最新压缩格式,压缩比很是高,若是你用其余格式,图片依然很大的话,这个格式将会成为你的神兵利器。
Crunch支持Android和IOS平台,能把图片压的很小,但图片质量有损失,能够经过调节质量百分比来解决。
Crunch在Editor下,计算压缩的时间很长,77张2048的图片要压缩5~8分钟左右。
对于大量贴图的更新来讲,整个团队的开发人员都要消耗至关长的时间来导入贴图,十分痛苦 很容易拉仇恨(说的就是我本身)。

参考资料:
《Unity性能优化以内存-贴图格式优化》https://segmentfault.com/a/11...
《Unity优化(一):图形优化》https://gameinstitute.qq.com/...
《[Unity优化] unity图片mipmap》https://www.jianshu.com/p/651...
《Unity 2017.3 中的Crunch纹理压缩库》https://www.sohu.com/a/204935...
《Unity官方文档Texture》https://docs.unity3d.com/Manu...

2.减小动画占用内存
总结一下优化动画的手段:
1.减少动画长度
2.减小骨骼数量
3.减小关键帧密度
4.减小动画精度

1.减少动画长度:
有些动画实际使用的的长度,远小于动画时长,若是有被加快使用的动画,应该考虑改短动画,下降大小,Animator里加快速度不会减小动画大小。

2.减小骨骼数量:
动画导入后,查看有无无效的骨骼点,删除这些节点能够下降动画大小。
(1)Animation里 骨骼点变成黄色说明缺乏该骨骼点,须要肯定是骨骼点丢失仍是不须要这些骨骼点,若是动画正常,则说明这些骨骼点无效能够删除。
无效骨骼点

(2)注意IK骨骼点 若是不须要使用反向动力学功能,而动画里又包含了IK骨骼点, 则删除这些骨骼点(一般是美工作完动画忘删IK了)。
无效IK点

3.减小关键帧密度:
启用FBX > Animation选项 > Anim.Compression选项 > Keyframe Reduction
Keyframe Reduction官方文档翻译:减小导入的冗余关键帧。若是选择,将显示动画压缩错误选项。这将影响文件大小(运行时内存)和如何评估曲线。

4.减小动画精度:
Unity存储Animation的数值精度比较高,能够经过减小数值精度的手段,下降动画大小。

参考资料:
《Unity骨骼动画资源解析与优化》https://www.cnblogs.com/damow...
《unity性能优化之下降动画文件的大小》https://blog.csdn.net/rhett_y...
《Unity 优化翻译官方文档(三) Animation Clips》https://blog.csdn.net/dengshu...

3.减小网格占用内存
1.减小顶点
2.开启Optimize Mesh选项
3.关闭Mesh Compression

1.减小顶点Vertex:
减小顶点会显著的提高网格的性能,减小内存的占用,一般来讲,在能够实现美术效果的前提下,顶点越少越好。

2.开启Optimize Mesh选项:
官方文档翻译:为了更好的GPU性能,顶点和索引将被从新排序。须要严格顶点排序的技术,如网格变形或特殊的粒子网格发射器效果,应该禁用此选项。

3.关闭Mesh Compression:
开始网格压缩可能会致使Optimize Mesh失败,占用更大的内存。

参考资料:
《Unity的Mesh压缩:为何个人内存没有变化?》https://www.cnblogs.com/muron...

4.减小音频占用内存
音频同时使用的数量较少,可是压缩比率大,默认音频格式加进内存后,体积会增大10倍。
对于较大的音频文件(超过200KB),要特别注意。
Load Type 改成 Streaming,能够极大下降内存占用。
建议较长的音频使用.mp3或.ogg格式,较短的音频使用.wav 或.aiff格式。

参考资料:
《Unity优化翻译官方文档(四) ------ Audio Clip》https://blog.csdn.net/dengshu...

5.减小材质占用内存

材质性能排行(由高到低):
1.Unlit 仅为纹理,光线不产生效果
2.VertexLit 顶点光照
3.Diffuse  漫反射
4.Normal Mapped 法线贴图
5.Specular 高光
6.Normal Mapped Specular
7.Parallax Normal Mapped
8.Parallax Normal Mapped Specular

尽可能用性能消耗更小的Shader来实现效果,复杂的Shader须要专人定制、管理和维护,写好Shader须要时间和经验的积累。

参考资料:
《Unity3D Shader性能排行》https://www.cnblogs.com/tim-u...
《UnityShader学习资料推荐》https://blog.csdn.net/wwlcsdn...
《Amplify Shader Editor手册(中文版)》https://blog.csdn.net/Debugge...

优化CPU

1.下降DrawCall
2.注意代码规范
3.内存换CPU
4.使用异步代替同步

1.下降DrawCall:
消耗CPU过大的状况很容易出如今图形渲染上,合并批处理,下降DrawCall能够极大的提高性能。好比使用动、静态批处理,GPU Instance技术。

2.注意代码规范:
良好的代码规范会让你得到更好的性能,而且避免不少陷阱,减小入坑的概率,节约时间。多读官方API,避免重复造轮子。

3.内存换CPU:
CPU不够时,不但能够想方法下降CPU的消耗,也能够考虑用内存换CPU。使用对象池就是一种常见的内存换CPU的手段。

4.使用异步代替同步:
使用异步Async(非阻塞式)代替同步Sync(阻塞式),能够优化用户体验。好比加载时用异步加载,显示进度条就属于这种方式。
可是一般异步比同步消耗的时间更多,遇到的问题更多,因此要合理使用异步和同步。

优化代码

《用好lua+unity,让性能飞起来——lua与c#交互篇》
https://www.cnblogs.com/zwywi...
《优化Unity游戏项目的脚本》
https://connect.unity.com/p/y...

参考资料:
《[Unity优化]减小DrawCall:批处理》https://blog.csdn.net/lyh916/...
《阿里巴巴Java代码规范》https://www.cnblogs.com/han-1...
《Unity官方文档-DrawCallBatching》https://docs.unity3d.com/Manu...
《Unity GPU Instance(大量相同网格物体合批)》https://segmentfault.com/a/11...
《Unity 对象池》https://blog.csdn.net/wangjia...
《Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条》https://www.xuanyusong.com/ar...

相关文章
相关标签/搜索