主要包括图集合批和打包的一些事情。
前面是一些碎碎念和一些实验,不想看的话可以跳到总结那一章。
参见https://docs.unity3d.com/2022.2/Documentation/Manual/SpritePackerModes.html
Mode选用Sprite Atlas V2 - Enabled,
现在有三张图片sp0,sp1,sp2,在一个图集tp中。
有一个图集tp,勾选Include in Build。
场景中有两个Image组件。
我把sp0打在一个AB包中AB0
我把sp1打在另一个AB包中AB1
我把sp2打在同一个AB包中AB1
现在我运行时加载AB包,AB0,从AB0中加载Sprite的sp0,赋给Image0组件。
现在我运行时加载AB包,AB1,从AB1中加载Sprite的sp1,赋给Image1组件。
会合批吗?
不会
现在我运行时加载AB包,AB1,从AB1中加载Sprite的sp1,赋给Image0组件。
继续从AB1中加载Sprite的sp2,赋给Image1组件。
会合批吗?
会
在同一个图集中,如果图集里的图片分散在不同的AB包中,那么无法合批。只有在同一AB包中的才能合批。原因下面会讲。
ClassTypes:
- Class: 28
Script: {instanceID: 0}
- Class: 213
Script: {instanceID: 0}
- Class: 687078895
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
- Assets/boss_skill_001.png
- Assets/boss_skill_002.png
Dependencies: []
注意到ClassTypes有三种,28对应Texture,213对应Sprite,687078895对应SpriteAtlas。表示这个ab包确实有SpriteAtlas。ClassType参见
为什么会有Texture呢?因为图集包含sprite,而原始sprite的格式就是Texture
奇怪的是在Assets下只有进包的图片,但是没有*.spriteAtlasv2。原因下面会讲。
ClassTypes:
- Class: 213
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
- Assets/boss_skill_001.png
- Assets/boss_skill_002.png
Dependencies: []
可以看到只剩下一个类型213就是Sprite
比较两个AB包的大小,包含图集的AB包为19k,不包含的为3k。很正常,因为图集存储需要空间。
图集有三张图,0和1在一个AB包中,2在另一个AB包中。
不勾选Include in Build时,大小为3k,2k
勾选Include in Build时,大小为19k,19k
也就是说同一个图集同时进了两个AB包,资源冗余。
勾选或者不勾选Include in Build,同时给图集单独打一个AB包,发现两个图片的AB包大小又变回了3k,2k。图集的AB包的大小为18k。
ClassTypes:
- Class: 28
Script: {instanceID: 0}
- Class: 213
Script: {instanceID: 0}
- Class: 687078895
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
- Assets/New Sprite Atlas.spriteatlasv2
Dependencies:
- G:/AB/b1.ab
- G:/AB/b3.ab
分析manifest文件,发现这个图集AB包依赖于另两个图片AB包。
勾选或者不勾选Include in Build,发现第一个AB包3k,第二个AB包19k
ClassTypes:
- Class: 28
Script: {instanceID: 0}
- Class: 213
Script: {instanceID: 0}
- Class: 687078895
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
- Assets/boss_skill_003.png
- Assets/New Sprite Atlas.spriteatlasv2
Dependencies:
- G:/AB/b1.ab
分析第二个AB包的manifest文件,发现这个包依赖于第一个包。
生成图集的时候,Sprite也会生成信息,指向该sprite对应的图集;
Include in Build,那么需要显式将图集打包。图集所在的AB包,会依赖于,图集包含的图片们所在的AB包。如果不勾选Include in Build,并且显式将图集打包,并且不打包图片,那么图集所在的AB包会自动隐式把图片包含进去,在Assets下没有图片,可以通过SpriteAtlas.GetSprite来获取图片。
Include in Build,那么没有必要显式打包图集,如果显式打包图集了,那么情况和不勾选Include in Build一样。Include in Build,在打包AB包的时候,该AB包内的图片如果在某个图集中,那么会隐式把这个图集包含进AB包中。Include in Build,在打包AB包的时候,如果图片A在第一个AB包中,图片B在第二个AB包中,那么图集会隐式打两份,一份在第一个AB包中,一份在第二个AB包中。Include in Build,请把一个图集中的所有图片放在一个AB包下,否则会造成资源冗余。Include in Build,那么manifest中不会把spriteatlasv2包含进去,隐式包含。Include in BuildAssetBundle.LoadAsset<SpriteAtlas>,然后取SpriteAtlas.GetSprite进行使用。Bundle中,那么需要先加载好图片所在的Bundle。sprite使用,大概率报错。因为该sprite索引到一个图集,我们需要把它所在的图集给它。SpriteAtlasManager.atlasRequested添加一个回调,根据传入的图集名称,我们加载AB包,从AB包中加载图集,提供之。Include in Build,并且没有手动把SpriteAtlas打进去Include in Build,那么manifest中不会把spriteatlasv2包含进去,隐式包含。因此无法通过LoadAsset<SpriteAtlas>找到图集。sprite用就是了,which正是Include in Build的目的。SpriteAtlasManager.atlasRequested加载并且返回图集。Resources.FindObjectsOfTypeAll<SpriteAtlas>来确认当前内存有多少图集。Include in Build,并且把SpriteAtlas打进了AB包Include in Build了