我研究SpriteAtlas的Include in Build的作用将近一天了,实在是头大,然后也不知不觉把丢失的英语给捡起来了。。。
首先官方的介绍:
https://docs.unity3d.com/Manual/SpriteAtlasDistribution.html
中文意思:不勾选Include in Build时,在发布的构建(项目)时,图集是不会包含在内的(assetbundle里依旧会有);在运行时也不会自动加载(我很想吐槽,运行时这么多种情况,到底时哪种情况?)
个人尝试:
unity版本:2019.2.21f个人版
注意:
图集能够正常在打包后使用,首先需要在project setting如下图设置
对图集进行Include in Build勾选状态的改变时,需要对其关联的所有ab包全部重新打一遍(后面会分析,为啥需要重新打一遍)。
例如从未勾选到勾选状态,重新打一遍ab包,否则在editor和发布的项目中,需要显示的图片依旧时空白状态。然后做资源前后对比,勾选时比不勾选时,用到图集的纹理的ab包(非包含spriteatlas的ab包)的信息会增加。
正式开始介绍:
以我测试文件为例:图集所在ab包名为atlastest,引用了图集内纹理的ab包为assetbundlecontent
对于Include in Build的勾选前后文件比较,assetbundlecontent与atlastest的大小均有改变。
未勾选时:
用assetbundle extrator查看内部的情况
勾选后(记得删除原来的ab包重新打,否则assetbundlecontent不会改变的)
经对比atlastest的大小和占用空间时不变的,但是atlastest文件本身是有改变的(怀疑是某个bool值变更了而已,勾选与不勾选的区别),用assetbundle extrator对比ab内的资源,是一样的
然后assetbundlecontent的比较,两者大小不一样(61676与62087),多了409bytes。assetbundle extrator比较,基本是一样的,除了一个assetbundlecontent,include in build 的情况为480bytes,未勾选时为452bytes。说明勾选与未勾选时,对于依赖这个图集的ab包是有影响的。
实际发布项目(build and run)
不勾选include in build时,图片全部是白的;勾选include in build时,图片是可以显示的。
回到官方的解释,官方说,其实不影响ab包,而是在发布项目的时候会有影响,那么果真如此么?
再做个试验:
未勾选include时发布应用(pc版 build and run),运行查看,确实没显示图片。然后我们不重新发布应用,而是替换应用中的assetbundlecontent,assetbundlecontent.manifest,atlastest,atlastest.manifest为未勾选include时生成的ab包,结果是:md
图片就可以正常显示了!!!
所以,官方文档上的解释你不是在骗我么,搞笑呢(我通过控制变量,证明include in build与工程发布没有关系,与ab包才是有关系啊)
那么再进一步考证,可能这个assetbundle使用的图集不是atlastest内的图集,我把atlastest删了,再次运行,图片变白了(说明确实引用了)
而经过上述比较,勾选include in build实际对包体的大小的影响实在是有限(8m的图集,勾选include in build,影响其依赖的ab包才几百bytes),图集上千,涉及万个依赖的ab包,也才几M啊(那你为啥不够选include in build呢)。
况且不勾选后,还需要进行late binding操作,参考:
https://docs.unity3d.com/ScriptReference/U2D.SpriteAtlasManager-atlasRequested.html,然后需要用到图集中的图片时,还需要经过加载目标spriteatlas才能使用(ab包不太好根据界面加载卸载管理图集的加载卸载啊)(经过测试,这个延迟绑定是有效的)(那你为啥不够选include in build呢)
那么勾选include in build,官方提及会automatically load it,意思是自动加载图集。那么我的疑问是这一块的内存是如何管理的呢,加载会自动释放么,需要我们手动卸载么,会一直在内存中存在么。这些我都没测试,目前也不知道该如何测试。
然后通过此次试验对于以前的贴子进行考证:
https://answer.uwa4d.com/question/5a822325847802258a06509e
经过上述测试过程,发现无论勾选不勾选include in build选项, 图集资源(atlastest包含的相关资源),并没有被assetbundlecontent重复包含(assetbundlecontent只有四个sprite,tree_1,tree_2,tree_3,tree_4,没有任何texture类型的资源)
这个帖子做了一定的解释,在Unity 2018.4.6中,Unity已经修复了这个问题:
https://www.cnblogs.com/murongxiaopifu/p/12453356.html
所以像这种还在讲include in build 时会造成打包资源冗余就是过时的(基本是uwa上的文章,md):
https://blog.uwa4d.com/archives/TechSharing_116.html
https://zhuanlan.zhihu.com/p/38341616
https://blog.csdn.net/akof1314/article/details/48376373
https://blog.csdn.net/UWA4D/article/details/82986037
(,实测,pc平台是与app包体无关的,换ab包就可以,帖子中提到的资源双份的情况也不存在,Unity 2018.4.6中已经修复了)
再补充一点的是:
我测试都是在pc平台,这里有个帖子提到在安卓真机也是我同样的情况,https://www.520mwx.com/view/9654(这个帖子引用的这里的讨论https://www.litefeel.com/unity-2017-new-sprite-atlas/#comment-28099)
(里面的人也犯了错,在进行include in build 操作后,没有重新打依赖这个图集的ab包。最好删除所有的再重新打ab包!!!)
然后就是
https://blog.csdn.net/u013052238/article/details/103293794
这个帖子提到的,勾选include in build ,如果找不到正确资源会触发SpriteAtlasManager.atlasRequested,这个试验还没做
总结:
在2019.2.21f版本测试:
include in build跟应用发布没有关系,只跟ab包的发布有关。用勾选了include in build的ab包替换未勾选的,就可以正常显示
include in build勾选后不会造成资源冗余,但会造成依赖此图集的ab包的会多出额外的信息(多出的内容无法查询,暂时也找不到资料),这些额外的信息占的空间几乎忽略不计,成百上千上万后,也不会对资源大小产生质的影响。
疑问:
include in build勾选后,图片是可以正常显示的,肯定是在ab包里的asset实例化时,图片实例化前,对图集进行加载了,这部分图集的内存管理是怎么样的?是否时常驻内存?是否需要手动管理?如果常驻内存,那么每次加载别的ab包,将其对应的图集也加载到内存并常驻了,这岂不是很糟糕?这些疑问可以参看这个下篇文章
游戏开发unity资源管理系列:SpriteAtlas的Include in Build的作用探究(下)
最后,因为我只对单个图集进行了研究,想必多个图集估计情况也是一样的。我不知道我的实验过程是否一定是准确的,然后看不到unity源码(非常不喜欢unity的这一点,但凡有疑问,只能靠官方,靠黑盒测试),不知道勾选Include in Build的真正影响哪些流程,欢迎大家在评论区留言讨论