Unity性能优化是面试的时候经常被问道的一些内容,今天给大家分享一些常用的Unity的优化技巧和思路,方便大家遇到问题时候参考与学习。
这里有个
包体大小优化
游戏的安装包体大小对于游戏开发而言非常重要,因为发布后这些包都会上传到渠道或商店让用户下载,包体越小用户下载的时间就越少,如果一个包体过大,可能导致好不容易推广的app,由于下载很久而直接被用户取消。包体大小优化技巧这里总结一下:
图片能用jpg的尽量使用jpg, 用压缩率更大的算法。
Jpg, png图片在满足游戏清晰度精度的情况下可以通过调节参数,压缩文件体积。
声音文件可以通过降低码率,采样率,多声道变单声道等方式降低体积大小。改变声音压缩算法,如.wav变成ogg来减少声音文件体积。
字体文件,可以通过去掉不用的字模来减少字库的体积。
3D模型文件体积, 可以通过减少模型的面数等来进行优化,通过细节增强技术减少模型面数达到同样的效果。
没有用的资源不要打包到包体里面,使用Resources, StreammingAssets时这些资源无论如何都会被打包进去,所以在这些文件夹中一些没有用的资源要移除或删除。
减少代码的体积,把不用的一些代码不编译打包进去。
可以把包体的全部或部分资源部署到服务器上,这样可以减少包体的体积大小。
内存大小/内存性能优化
游戏开发中运行的内存过大,是经常我们遇到的问题,内存包含了运行时候的内存以及资源所占的显存。如何优化内存所占的大小,我们也可以从几个方面去考虑。
内存大小与数据量是成直接关系的,平常写代码的时候,尽量的要用好内存,少用内存。
游戏开发中资源所在的内存占比是比较大的,资源所在的内存包括了模型顶点数据,模型纹理数据,UI纹理数据,声音数据,预制体数据,ab包数据等。这些和上面的文件体积不同,比如 1920x1080的jpg与png, 不论是哪个文件加载到显存的大小都为 1920x1080 * 每个像素的字节数(4字节)。所以我们要减低运行时的内存就是要即使的将不用的资源从内存中释放掉。有些资源的内存格式显卡时支持要锁的,比如Android支持ETC, IOS支持纹理压缩格式PVRTC。
写代码的时候尽量少产生垃圾对象,避免性能问题与内存碎片。比如字符串拼接,尽量用字符串的格式化来替代字符串加法。因为你很难说清楚
string a = “hello” + b + “hello” + 4;
这个过程中到底又多少个string对象产生出来。在update里面尽量不要写那些每帧都会去new 的代码,避免产生内存碎片。同时我们为了性能,把同时大量重复使用的对象做成对象节点池缓存起来,杜绝反复创建避免内存碎片。
所以写代码的时候要考虑到这些因素,写出内存占用低性能比较好的代码。
写代码影响帧率的一些不良习惯
接下来我们来列举一些写代码会影响帧率的不良习惯,希望能帮助大家避免掉一些帧率上不去的坑。
不要在update里面每帧的时候去调用查找组件这些函数,最好在初始化的时候先查好保存起来。
不要在游戏运行中同步的去加载一个资源,导致代码卡在了在原加载的函数上,比如加载一个资源要0.5s, 如果运行时同步去加载资源就会卡0.5秒,那么在0.5秒内游戏就卡住了,帧率就降到为1~2。
不要在游戏运行中做IO操作,比如游戏运行中同步的读写文件,这样就会导致main thread 去等IOS,导致帧率下降。
不要把耗时的纯算法的操作放main thread中,比如要计算某个NPC的一个结果,这个计算可能需要花1秒钟,但是1秒内其它的NPC或角色都可以正常的处理,我们不要在主线程上来计算这个算法,而是通过线程的方式,在其它线程计算不卡主线程影响其它的逻辑。等其它线程计算好后通知主线程。这样游戏帧率不会下降,同时又不会影响游戏,比如寻路算法等都可以用这种方式来做。
误以为协程不会帧率,很多开发者在写代码的时候把一些操作放协程,认为不会降低帧率,其实协程也在主线程执行,会影响帧率。
渲染相关的优化技巧
如何提升游戏物体的渲染性能也是很多开发者摸不清楚的,在这里给大家总结一下常用的思路和技巧,给大家在做渲染优化的时候做一个参考指南。
通过3D细节增强的技术(法线贴图,高度贴图等),来降低模型精度,让低模+细节增强来实现高模的效果。
尽量让美术以少的模型面数来制作效果好的模型。
做好场景的物体管理(四叉树场景管理),把那些不用绘制的物体隐藏起来,节约绘制的成本。
基于反画家算法从后向前渲染,尽量减少透明物体,尽量把背景的大物体分成多个小物体,做遮挡剔除的时候会更好。
可以考虑使用静态光照来做场景烘培, 代替实时光照。
可以考虑使用贴图来做物体的阴影,代替实时阴影。
如果要用实时光照,尽可能的用一种光源。
如果要用实时光照,又不会只有一种光源,尽可能的使用延时渲染或其它自定义的渲染管线(轻量级渲染)来代替向前渲染。因为向前渲染每个光源都要绘制一次,性能影响很大。
场景多光源的情况下,根据场景物体的位置,管理好有效光源,无效光源不参与物体计算,这里的策略可以通过定制渲染管线。
Shader 相关的优化,空间换时间, 多光源光照计算优化与阴影计算优化等。
绘制同一批物体的时候,尽量用同一个shader, 减少Shader的切换, Shader切换又叫SetPassCall, SetPassCall非常消耗性能,同时把常用的Shader加载到内存常驻。
避免Shader不断重复交叉切换。
尽量把一些物体合并到一个材质里面,比如玩家手里的枪,可能有很多支,但是我们把所有枪的纹理合并到一个纹理里面,就可以使用一个材质来渲染任意枪的类型,这样可以合并一些枪的drawcall。比如可以把地图里面的物体贴图合并到一个忒图里面用一个材质。
可以考虑使用 静态合批,动态合批,GPU Instancing合批来节约DrawCall。UGUI可以通过做图集来节约DrawCall。
通过预先采样将顶点保存起来优化动画播放组件。
物理引擎相关优化技巧
物理引擎也是性能开销很大的一个点,很多物理刚体比较多的游戏帧率下降的比较厉害,如何优化物理引擎可以从一下方面来考虑:
尽可能的减少的刚体数目,刚体的数目决定了物理引擎的计算成本。
尽可能的使用性能高的物理形状捧起,避免复杂的物理形状碰撞器。球型碰撞器的性能就要大于刚体碰撞器。
调整一些物理参数,减少物体的迭代次数来提升物理引擎的性能。
更换性能更好的物理引擎,或者更换某个方面更好的物理引擎。
自己根据游戏的需求自己实现一个性能高的阉割版“物理引擎”。
今天的性能优化技巧总结与分享就到这里,希望大家在工作中 对Unity性能优化提供一些帮助。