Unity2017带来了新的SpriteAtlas工具,该工具可以方便的将碎图打包成纹理集,相比于之前SpritePacker工具,SpriteAtlas将统一的管理纹理集,不必再到每个碎图上查看被打包到了哪个纹理集,并且解除了sprite使用者和纹理集的强依赖关系。
创建纹理集
- 设置 Editor Settings 中 Sprite Packer 的 Mode 为
Always Enabled
- 通过 Project 面板的右键创建 Sprite Atlas
- 选中创建的 Sprite Atlas, 并在 Inspector 面板的 Objects for Packing部分添加 sprite
- 点击 Pack Preview 按钮预览合并的纹理集
- 当 UI 使用这些 Sprite 时,将自动使用打包的纹理集中的 sprite
注意: 一定要将包含的 Image 的 Texture Type 设置成 Sprite(2D and UI), 否则不能真正包含到 Sprite Atlas 里。
工作流
一定不能将原始纹理集从 Unity 的 Assets 目录中移除,否则将不能正常显示。 即使是被打包到了Asset bundle里也不能删掉原始的纹理集。
新纹理集在编辑器和发布后的Player中表现稍有不同。
这里先说在编辑器中最简单的使用方式。
- 勾选纹理集的 Inspector 面板中的
Include in Build
选项,否则需要在SpriteAtlasManager.atlasRequested
回调中手动填充纹理集 - 将 sprite 拖到 Image 的 Source Image 属性上
- 点击运行,正常显示
上面的方式相当于将所有内容都打包到该场景中,对于只有少量资源的小项目可以接受。但是有太多资源就不能这么做了,必须要将这些资源分散到不同的 Asset bundle 中。
引入AssetBundle
将不同的纹理集及 UI 分离到 Asset bundle 中,那么流程基本不变,只是需要注册 SpriteAtlasManager.atlasRequested
事件,并处理。
类似下面的代码
using UnityEngine; using UnityEngine.U2D; public class SpriteAtlasManager : MonoBehaviour { void Awake () { // 注册事件 SpriteAtlasManager.atlasRequested += OnAtlasRequested; } private void OnAtlasRequested(string tag, Action<SpriteAtlas> action) { // 加载纹理集 // unity2017.1版本:当收到回调后必须立刻用纹理集填充 // SpriteAtlas atlas = LoadAtlas(tag); // action(atlas); // 2018.2.1f1版本:可以异步加载纹理集,只需向action回调填充纹理集就可以了 // 当纹理集没有被填充前,Image等组件将显示为默认的白色纹理 // 一旦纹理填充后,Image等组件将自动显示为正确的纹理 StartCoroutine(DoLoadAsset(action, tag)); } private IEnumerator DoLoadAsset(Action<SpriteAtlas> action, string tag) { yield return new WaitForSeconds(3); var ab = AssetBundle.LoadFromFileAsync(getpath(tag)); yield return ab; print("DoloadAsset frame:" + Time.frameCount); var sa = ab.assetBundle.LoadAsset<SpriteAtlas>(tag); print("sa: " + sa); action(sa); } }
在 Unity 编辑器中,点击运行,会立刻请求所有的纹理集。
而Player中运行时,则于我们预期的一致,只回调使用到的纹理集。
注意事项
- 总是启用
Always Enabled
,默认是Disabled
,菜单路径:
Edit > Project Settings > Editor > Sprite Packer > Mode
- 纹理集 Inspector 面板上的
Include in Build
选项,仅作用于编辑器中。如果勾选就在点击运行时自动加载纹理集,否则不自动加载,并触发SpriteAtlasManager.atlasRequested
事件。 - 纹理集中的图片的纹理类型需要设置为
Sprite (2D and UI
- 编辑器中的原始纹理集一定不能删除。
- 不同电脑上的纹理集的.meta文件中的hash会不一样,建议只在一台电脑上打包assetbundle,其他电脑忽略.meta文件的变化。不要提交。
结尾
新的纹理集相比旧版本的SpritePacker,最大的改进是解除了纹理及与UI的强引用关系,只使用tag来关联,使得应用多套资源更方便。
Unity 2017.1是新纹理集的第一个版本,虽然还有一些不太方便的地方,但是相信在后面的版本迭代中会越来越好。
2018/07/29更新
unity2018.2.1f1已经完美支持Late Binding,也就是可以在收到SpriteAtlas.atlasRequested
回调后延迟填充纹理集,避免同步加载造成卡顿。
看到留言说Prefab中使用纹理集会造成资源重复打包,在AssetBundleBrower中确实看到资源被自动打包到不同的包,但是从打包后的bundle大小来看,应该是AssetBundleBrower的误报。
以上测试均使用unity2018.2.1f1版本。
SpriteAtlas测试项目 https://github.com/litefeel/UnitySpriteAltasTest
www.litefeelcom | Host on Linode VPS refcode: e99568e929b474fd25dec4e734d04e7d08e8b42c