Unity图集 SpriteAltas 打包探究
本文由 NRatel 历史笔记整理而来,如有错误欢迎指正。
一、基本设定/预先测试结论
1、Include in Build 字面意思辨析(易错!!!实际上它有两层含义)
先看文档中的描述,非常模糊:
https://docs.unity3d.com/2021.3/Documentation/Manual/class-SpriteAtlas.html
1、Build App 时,若图集勾选 IncludeInBuild,则 满足以下情况时,图集被打入 App
1、图集关联的碎图被 首场景依赖
2、图集关联的碎图被 Resources 下的文件依赖
3、图集放在Resources中(这条是必然的,主要是说上2条)
2、Build AB 时,若图集关联的碎图被打包,则图集会被打入关联的碎图的ab中。
2、Include in Build 对绑定的影响
1、若勾选了 Include in Build,当加载一个关联了 SpriteAtlas 的 Sprite 时,Unity会自动绑定 Sprite 所在的图集
2、若未勾选 Include in Build,当加载一个关联了 SpriteAtlas 的 Sprite 时,SpriteAtlasManager.atlasRequested 会被调用(应在其中加载并返回图集,以完成后期绑定)
3、Include in Build 勾选选择(通常应该勾选)
1、以 Resources 方式进包的资源,应勾选,走自动绑定
2、无动态绑定需求(如异步下载加载、根据高低配赋予不同图集等),应勾选
4、当不勾选 Include in Build,进行动态绑定时,
1、如果加载一个关联了 SpriteAtlas 的 Sprite,若未为 SpriteAtlasManager.atlasRequested += 任何事件,会产生一个警告
2、若未在 SpriteAtlasManager.atlasRequested 中正确返回 altas,则 Sprite 在 Load 后不会正常显示(白片)
3、图集被首次绑定时,总表现为有一帧闪烁(白图或花图),原因是:SpriteAtlasManager.atlasRequested 总会比打开预设的逻辑 晚1帧执行,有1帧间隔。
5、SpriteAltas 和 Sprite 设置不同的压缩格式,会怎样?
两者的压缩效果会生效2次,即:碎图在拼入图集时先执行了一次压缩。但总体图集的最终大小只由图集的压缩格式决定。如果碎图设置压缩格式,平白损失清晰度。应总是将碎图的压缩格式设为 RGBA32!!!
似乎在有些Unity版本中,如果图集中的碎图没有使用 RGBA32,会产生一个警告,映像里见过,但我没截到图。
6、当不勾选 Include in Build,进行动态绑定时,SpriteAtlas 中包含的碎图不能同名,即使所在子目录不同也不行。会随机返回一个。
7、当主动加载图集,并从图集中加载碎图时,SpriteAtlas 中包含的碎图不能同名,即使所在子目录不同也不行。会随机返回一个。
8、当勾选 Include in Build,无论 显示由预设自动引用的碎图 还是 从 Sprite ab加载碎图时,SpriteAtlas 中包含的碎图可以同名,Untiy能够自动准确索引到对应碎图。
二、AB打包测试环境
Unity2021.3.42f1c1
需要安装 package:2D Sprite
资源构建管线:分别测试 SBP 1.20.2(Untity2021默认推荐版本)和 SBP 2.1.5
注意,内置管线与SBP的构建结果也不同,这里不做测试
图集和碎图:Test 图集关联 test1.png 和 test2.png(图集和碎图都不位于 Resources 中,也不被首场景依赖。)
图集勾选 Include In Build
三、AB打包测试(SBP 1.20.2)
1、只对 Sprites 打 ab
ab内容物(Texture2D冗余):
1、完整图集的 Texture2D
2、所有碎图的 Texture2D
3、所有碎图的 Sprite
ab依赖情况:不存在依赖关系
2、只对 SpriteAtlas 打 ab
ab内容物(正常):
1、完整图集的 Texture2D
2、所有碎图的 Sprite
ab依赖情况:不存在依赖关系
3、将 Sprites 和 SpriteAtlas 打到一个 ab 中
ab内容物(Texture2D冗余):
1、完整图集的 Texture2D
2、所有碎图的 Texture
3、所有碎图的 Sprite
ab依赖情况:不存在依赖关系
4、将 Sprites 和 SpriteAtlas 打到不同 ab 中
ab内容物1(图集)
1、完整图集的 Texture2D
ab内容物2(碎图)
1、所有碎图的 Texture
2、所有碎图的 Sprite
ab依赖情况:产生了 依赖自身 和 互相依赖(循环依赖)
四、比较优缺点(SBP 1.20.2)
1、只对 Sprites 打 ab
优点:1、可直接加载 Sprites 所在 ab(无感图集)
缺点:1、ab内容物不正常(包含:完整图集的 Texture2D、所有碎图的 Texture2D、所有碎图的Sprite)(Texure2D 翻倍)2、无法主动加载 SpriteAtlas
2、只对 SpriteAtlas 打 ab
优点:1、ab内容物正常(ab中包含)2、可主动加载 SpriteAtlas
缺点:1、只能先加载图集,再加载碎图(业务逻辑中需关心图集)
3、将 Sprites 和 SpriteAtlas 打到一个 ab 中
优点:1、可直接加载 Sprites 所在 ab(无感图集)2、可主动加载 SpriteAtlas
缺点:1、ab内容物不正常(包含:完整图集的 Texture2D、所有碎图的 Texture2D、所有碎图的Sprite)(Texure2D 翻倍)
4、将 Sprites 和 SpriteAtlas 打到不同 ab 中
优点:1、动态碎图加载时,可直接加载Sprites所在ab(无感图集)2、可主动加载 SpriteAtlas
缺点:1、ab内容物不正常(包含:完整图集的 Texture2D、所有碎图的 Texture2D、所有碎图的Sprite)(Texure2D 翻倍)2、存在循环依赖
五、可选择(SBP 1.20.2)
1、选择 方案 1,并解决 Texture2D 重复的问题(修改 SBP BuildTaskList 插入一些自己的处理)(已在网上看到这样的做法)
2、选择 方案2,但接受:业务逻辑中按 图集+图名 的方式动态加载碎图。(虽然还可以自己去维护一个 碎图到图集的映射,去做路径解析,但还是无法解决 图集中存在多个同名碎图的加载(不同子目录)的问题)
3、选择 方案 3(支持两种用法),并解决 Texture2D 重复的问题(修改 SBP BuildTaskList 插入一些自己的处理)(同1)
4、选择 方案 4,并解决 Texture2D 重复 和 依赖错误的问题(难度较大,建议直接放弃)
六、新版本的SBP尝试
根据 SBP 更新日志,从 2.0.1开始,已经解决了 Texture2D 重复的问题(只对 Sprites 打 ab)
1、尝试引入 SBP 2.0.1 失败了,无法引入
2、在 SBP 2.1.0 中测试,仍存在问题
3、在 SBP 2.1.3~2.1.5 中,确认已修复(未测试更新版本,因为更新版本在 Unity 2021.3.x 中不可用)(见下方 2.1.5 的详细测试)
七、AB打包测试(SBP 2.1.5)
1、只对 Sprites 打 ab
ab内容物(正常):
1、完整图集的 Texture2D
2、所有碎图的 Sprite
ab依赖情况:不存在依赖关系
2、只对 SpriteAtlas 打 ab
ab内容物(正常):
1、完整图集的 Texture2D
2、所有碎图的 Sprite
ab依赖情况:不存在依赖关系
3、将 Sprites 和 SpriteAtlas 打到一个 ab 中
ab内容物(Texture2D冗余):
1、完整图集的 Texture2D
2、所有碎图的 Texture
3、所有碎图的 Sprite
ab依赖情况:不存在依赖关系
4、将 Sprites 和 SpriteAtlas 打到不同 ab 中
ab内容物1(图集)
1、完整图集的 Texture2D
ab内容物2(碎图)
1、所有碎图的 Sprite
ab依赖情况:产生了 依赖自身 和 互相依赖(循环依赖)
八、比较优缺点(SBP 2.1.5)
1、只对 Sprites 打 ab
优点:1、可直接加载 Sprites 所在 ab(无感图集)
缺点:1、无法主动加载 SpriteAtlas
2、只对 SpriteAtlas 打 ab
优点:1、ab内容物正常(ab中包含)2、可主动加载 SpriteAtlas
缺点:1、只能先加载图集,再加载碎图(业务逻辑中需关心图集)
3、将 Sprites 和 SpriteAtlas 打到一个 ab 中
优点:1、可直接加载 Sprites 所在 ab(无感图集)2、可主动加载 SpriteAtlas
缺点:无
4、将 Sprites 和 SpriteAtlas 打到不同 ab 中
优点:1、动态碎图加载时,可直接加载Sprites所在ab(无感图集)2、可主动加载 SpriteAtlas
缺点:1、存在循环依赖
九、可选择(SBP 2.1.5)
1、选择方案1,放弃加载图集的用法,能满足大部分项目所需(无预加载图集的需求,即使有,也可触发加载某个图集中的图)
2、选择 方案2,但接受:业务逻辑中只能按 图集+图名 的方式动态加载碎图。(虽然还可以自己去维护一个 碎图到图集的映射,去做路径解析,但还是无法解决 图集中存在多个同名碎图的加载(不同子目录)的问题)
2、选择方案 3(支持两种用法),但需考虑 图和图集 怎样放置,才能方便得打到一起
3、选择 方案 4,并解决依赖错误的问题(未尝试,不知是否可行)
十、最终/推荐采用方案
将项目 SBP 升级到 2.1.5。
选择方案1,只对 Sprite 打ab。
若项目资源的放置规则,也可考虑选择方案3。