Unity2017的新spriteAtlas

发表评论 阅读评论

Unity2017带来了新的SpriteAtlas工具,该工具可以方便的将碎图打包成纹理集,相比于之前SpritePacker工具,SpriteAtlas将统一的管理纹理集,不必再到每个碎图上查看被打包到了哪个纹理集,并且解除了sprite使用者和纹理集的强依赖关系。

创建纹理集

sprite atlas

  1. 设置 Editor Settings 中 Sprite Packer 的 Mode 为 Always Enabled
  2. 通过 Project 面板的右键创建 Sprite Atlas
  3. 选中创建的 Sprite Atlas, 并在 Inspector 面板的 Objects for Packing部分添加 sprite
  4. 点击 Pack Preview 按钮预览合并的纹理集
  5. 当 UI 使用这些 Sprite 时,将自动使用打包的纹理集中的 sprite

注意: 一定要将包含的 Image 的 Texture Type 设置成 Sprite(2D and UI), 否则不能真正包含到 Sprite Atlas 里。

工作流

一定不能将原始纹理集从 Unity 的 Assets 目录中移除,否则将不能正常显示。 即使是被打包到了Asset bundle里也不能删掉原始的纹理集。

新纹理集在编辑器和发布后的Player中表现稍有不同。

这里先说在编辑器中最简单的使用方式。

  1. 勾选纹理集的 Inspector 面板中的 Include in Build 选项,否则需要在SpriteAtlasManager.atlasRequested回调中手动填充纹理集
  2. 将 sprite 拖到 Image 的 Source Image 属性上
  3. 点击运行,正常显示

上面的方式相当于将所有内容都打包到该场景中,对于只有少量资源的小项目可以接受。但是有太多资源就不能这么做了,必须要将这些资源分散到不同的 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) {
        // 加载纹理集
        // 当收到回调后必须立刻用纹理集填充
        SpriteAtlas atlas = LoadAtlas(tag);
        action(atlas);
    }
}

在 Unity 编辑器中,点击运行,会立刻请求所有的纹理集。
而Player中运行时,则于我们预期的一致,只回调使用到的纹理集。

注意事项

  1. 总是启用 Always Enabled,默认是 Disabled,菜单路径:
    Edit > Project Settings > Editor > Sprite Packer > Mode
  2. 纹理集 Inspector 面板上的 Include in Build 选项,仅作用于编辑器中。如果勾选就在点击运行时自动加载纹理集,否则不自动加载,并触发SpriteAtlasManager.atlasRequested事件。
  3. 纹理集中的图片的纹理类型需要设置为 Sprite (2D and UI
  4. 编辑器中的原始纹理集一定不能删除。
  5. 不同电脑上的纹理集的.meta文件中的hash会不一样,建议只在一台电脑上打包assetbundle,其他电脑忽略.meta文件的变化。不要提交。

结尾

新的纹理集相比旧版本的SpritePacker,最大的改进是解除了纹理及与UI的强引用关系,只使用tag来关联,使得应用多套资源更方便。

Unity 2017.1是新纹理集的第一个版本,虽然还有一些不太方便的地方,但是相信在后面的版本迭代中会越来越好。

标签: ,

  1. |

    谢谢您的分享,我是这样用的
    1、将散图资源做成一个spritearlas,将这个spritearlas打包成AB,散图资源不打AB包
    2、导出window版本,在window版本上,通过代码读取spritearlas的AB资源,并通过名字来获取里面的图片信息,显示之,能正常显示,达成目的,此时AB资源中只有spritearlas,没有散图资源。
    3、第2步是测试通过代码读取spritearlas的图片资源并显示,可行。但是不通过代码读取,如有一个image,上面直接给sprite一个图片,注册了SpriteAtlasManager.atlasRequested之后仍然显示不了(非编辑器模式,window包下),请问这种情况如何处理?

  2. | |

    @花底滑
    1. 注册SpriteAtlasManager.atlasRequested一定要在加载要用的spriteAtlas的AB之前
    2. OnAtlasRequested 中一定要同步填充 spriteAtlas,不能异步

  3. |

    请问一下,

    之前一直用的散图,最后包很大,想用sprite atlas打包做压缩,但是打包成atlas之后,散图不删除的话,还是会被打到包里面。这样反而会因为多出了atlas多一些资源。

    删除了散图的话,又不能正常显示,这个应该怎么处理?

    理论上来说,atlas应该直接替换散图才对啊

  4. | |

    @Dinko
    没有发现会重复打包的情况,你可以比对下assetbundle的大小

  5. |

    感谢分享,想问下,都有哪些情况会触发atlasRequested回调?

  6. |

    @liudq
    我自己做的测试,Awake时,注册了atlasRequested回调并加载有SpriteAtlas的AB包,在回调里,填入AB包里的SpriteAtlas,这样测试是正常可以显示出Sprite的。但如果,我只是在Awake里注册回调,并隔几秒再执行加载AB包,就不显示Sprite。请问这种情况如何处理?

  1. 本文目前尚无任何 trackbacks 和 pingbacks.
回到顶部