听说你的项目中仅这些资源就卡成了翔?看看他们怎么做!

听说你的项目中仅这些资源就卡成了翔?看看他们怎么做!

项目中的冗余资源本身会在项目文件中占据额外的空间,还有可能在内存中多次被加载,占据内存。笔者通过UWA提供的资源检测与分析,定位到所有AssetBundle中包含的冗余资源,轻松对这些资源执行定点优化。具体怎么做的,让我们来看看详细的实现步骤吧。

这是侑虎科技第141篇原创文章,感谢作者李勇(QQ:233242872)供稿。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群465082844)

同时,作者也是U Sparkle活动参与者哦,UWA欢迎更多开发朋友加入 U Sparkle开发者计划,这个舞台有你更精彩!


目录

1、目标
2、检查
3、迭代优化
4、额外收益
5、结合unity Profiler优化内存占用
6、总结


一、目标

优化AssetBundle(下文简称AB),一方面降低了AB的大小、包体大小,另外一方面也能减小AB加载时所占用的内存,从而降低游戏因内存不足崩溃的概率。同时通过对AB中包含资源的深入分析,可以避免将一些旧的资源错误打入到AB中。

二、检查

1.Unity 4.x的AB打包是手动管理依赖,非常麻烦,而Unity 5.x自动管理AB之间的依赖,大大降低了开发负担。手动管理有点类似于C语言直接用指针,控制性强,但是极其容易出错;而自动管理依赖,会导致对AB资源打包原理的缺少分析和关注,使得对AB的优化不够。

打包的基本策略:将公共依赖的资源打入到一个公共AB中,其它AB依赖于公共AB。

我们使用的是Unity 5.x, Unity 5.x中打包AB有两种方式:一种是直接在编辑器中为每个资源设置其所属于AB的名字; 另外一种方式是在代码中,设置每个AB包含哪些资源路径。我们采用的是第二种方式,即在代码中指定。

2.我们在UWA(www.uwa4d.com)上提交了若干次资源检测,逐步优化掉了一些AB打包中的问题。下图就是我们多次测试的记录:

0.png
UWA中的AB资源检测界面,主要分为两个栏目:一个是以AB为观察对象,另外一个是以 资源本身为观察对象。
请输入图片描述

第一次检测的结果,可以看到很多AB中有冗余的资源。点击“资源使用”栏目,可以查看哪些资源冗余了,一般都是些Shader,材质,纹理,Sprite,动画之类的资源冗余。
请输入图片描述

如下图,我们还能看到资源冗余的具体情况:
请输入图片描述

在此,我们看到有大量的Sprite冗余,因为我们游戏的每个UI都单独打了一个AB包,而UI公共使用的一些Sprite没有打入到公共AB中,导致这些Sprite被打入到了每个UI AB中, 而Sprite对应的纹理,也被打入到了这些UI的AB中。解决方案:额外加一个公共AB,将这些Sprite打入到这个AB中。使UI AB依赖于这个公共AB。

材质的冗余
主要是废弃掉的粒子效果仍然被打入到了AB中,删除掉这些粒子效果即可。

动画冗余
忘记将UI动画打到公共AB中了,把动画目录添加到公共AB即可。

Shader冗余
每个材质被单独打到独立的AB中了,导致材质用的Shader被重复打入。这里之前有个误区:将Shader放到一个Prefab中,将Prefab打入到公共AB中,并不能使这些材质AB依赖于这个公共AB, Unity5.x中 AB之间的依赖必须是显式的,而不能是隐式的,必须显式地将Shader的路径加入到公共AB中,才能使材质AB依赖于公共AB。

Font冗余
错误地使用了一个旧的字体,解决办法是调整所有使用旧字体的UI。

Mesh冗余
模型打AB的时候,忘记处理导致。

三、迭代优化,验证

发现了这些冗余资源,新增一个公共AB,将冗余资源全部打入其中。运行时,首先加载这个公共AB里面所有的资源。

最后的优化结果:
请输入图片描述
剩下两个Sprite是错误引用了Unity自己的资源,可以调整相关UI去掉对应的应用。

Texture2D中,一个是上面错误的Sprite使用对应的纹理;一个是角色模型的材质中引用到的纹理,没有打入到公共AB中;还有三个比较特殊,这三个纹理对应的Sprite已经打入到公共AB中了,但是在UI中,是以RawImage的方式引用到这几个Sprite。RawImage引用的Sprite,都相当于直接引用纹理,而不是sprite,导致不能使用公共AB,修正方法额外复制一份这些sprite,设置其importe typ为texture,将这些Texture2d打入到公共AB中。

Mesh模型,可以将其打入到公共AB中即可。

可以看到要完全优化掉这些冗余资源,还需要对现有的UI等做一些修改,所以AB优化不单单是只优化打包流程就可以的哦。

四、额外的收获

通过查看每个AB中包含哪些资源可以发现一些问题。

1.首先是我们的Sprite竟然都没有打包成Sprite atlas。
请输入图片描述

可以看到,UI纹理都是一张张碎图。究其原因,一是Sprite没有设置packingtag,二是 Sprite都放在Resources目录下面,导致打包AB的时候,Resources目录下的Sprite是不会生成图集的。因此调整一下打包代码,打包的时候将这些Sprite移动到resources外面某个目录中,打包AB结束再放回去。
请输入图片描述

如上就是正常的结果,可以看到texture2d的名字都叫做spriteatlas 了。

2.发现一些旧的Sprite也被打包进了AB中,利用UWA工具,非常容易找到所有引用到旧资源的UI,在Unity中调整,去掉对旧资源的引用。

五、结合Unity Profiler优化内存的占用

AB的冗余去除掉了,但是优化还没有结束。编译一个Development的程序,设置连接到Profiler。在Profiler中查看内存的使用情况如下,可以看到纹理内存占用大大降低了。
请输入图片描述

之前50-60MB, 优化后20-30MB。接着做一次内存采样,看一下每个纹理的内存大小:
请输入图片描述
可以看到有些图特别大,是因为没有设置为压缩格式导致的,iOS是PVRTC, Android是 ETC1格式。设置为压缩格式品质会有一些降低,但是内存和加载速度会优化。

六、总结

总之,使用UWA的资源检测与分析工具,可以非常直观地看到所有的AssetBundle以及资源的状态,帮助我们进行更高效的资源分析和优化。

文末,再次感谢李勇的分享,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群465082844)。
也欢迎大家来积极参与U Sparkle开发者计划,简称"US",代表你和我,代表UWA和开发者在一起!