【Unity】Sprite Atlasの実装(Assetbundleにも対応)
本記事で扱うUnityのバージョンは「Unity2018.3.7f1」です。
Spriteをパッキングする機能。
複数枚の画像を一つの画像にする。
処理が軽くなります。
描画回数(Set Pass Calls)を節約できます。
こんな感じに
画像4枚をそのまま配置 → +4のSetPassCalls
画像4枚をSpriteAtlas化 → +1のSetPassCalls
Project → Create → Sprite Atlasを選択
spriteAtlasファイルが作られます
Sprite Altasの設定
・Type
Masterのまま
・Include in Build
AssetBundleのときはチェックを外す
・AllowRotation
uGUIで使用する際に表示崩れが起きるのでチェックは外す。本来はアトラスのサイズを抑えるためのもの。
・Tight Packing
uGUIで使用する際に表示崩れが起きるのでチェックは外す。本来はアトラスのサイズを抑えるためのもの。
・Padding
4のまま
パッキング
Objects for Packingという項目から、+ボタンでパッキングするSpriteを選択します。
選択できたらPack Previewを選択します。
こんな感じでパッキングされます。
パッキングした元のSpriteを使用します。
SpriteRendererの場合はそのまま配置、
uGUIの場合はImageにつけたりと通常のSpriteと使用方法は同じです。
SetPass calls
【実行前】
Game ViewのStatsより確認できます。
実行前はまだAtlasの効果は出ていません。
【実行後】
実行するとSetPass calls減っているのがわかります。
・カメラ +1
・Atlas +1
uGUIだと実行前から効果がでています。
なぜか。
AssetBundleでの使用方法
AssetBundleで使用する場合は、Sprite Atlasの設定のInclude in Buildのチェックを外します。
AssetBundleを読み込む際に、
SpriteAtlasManagerのatlasRequestedを使用します。
docs.unity3d.com
サンプルコード
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.U2D; public class SpriteAtlasLoad : MonoBehaviour { /// <summary> /// アセットバンドル名。 /// </summary> [Header("アセットバンドル名")] [SerializeField] string assetBundleName = null; /// <summary> /// アセット名。 /// </summary> [Header("アセット名")] [SerializeField] string assetName =null; [Header("イメージ")] [SerializeField] Image img = null; /// <summary> /// AssetBundle。 /// </summary> AssetBundle assetBundle; void Awake() { assetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + assetBundleName); img.enabled = false; } void OnEnable() { SpriteAtlasManager.atlasRequested += OnAtlasRequested; } void OnDisable() { SpriteAtlasManager.atlasRequested -= OnAtlasRequested; } void OnAtlasRequested(string tag, System.Action<SpriteAtlas> atlasCallback) { var request = assetBundle.LoadAssetAsync<SpriteAtlas>(assetName); request.completed += (operation) => { atlasCallback.Invoke((SpriteAtlas)request.asset); img.enabled = true; }; } }
一応普通に読み込んだSpriteAtlasから参照して取れますが、
Warningが出ます。
サンプルコード
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.U2D; public class SpriteAtlasLoad : MonoBehaviour { /// <summary> /// アセットバンドル名。 /// </summary> [Header("アセットバンドル名")] [SerializeField] string assetBundleName = null; /// <summary> /// アセット名。 /// </summary> [Header("アセット名")] [SerializeField] string assetName =null; /// <summary> /// スプライト名。 /// </summary> [Header("スプライト名。")] [SerializeField] string spName = null; /// <summary> /// イメージ。 /// </summary> [Header("イメージ")] [SerializeField] Image img = null; /// <summary> /// AssetBundle。 /// </summary> AssetBundle assetBundle; void Awake() { assetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + assetBundleName); } void Start() { var request = assetBundle.LoadAssetAsync<SpriteAtlas>(assetName); request.completed += (operation) => { var atlas = (SpriteAtlas)request.asset; var atlasSp = atlas.GetSprite(spName); img.sprite = atlasSp; }; } }
atlasRequestedを使えと!
モバイルで作る際にはどうしても必要な機能かと思います。
AssetBundleで使う際は少し癖はあるかと思いますが、
使い方さえ間違わなければとても強い味方。
kan-kikuchi.hatenablog.com
tsubakit1.hateblo.jp
tsubakit1.hateblo.jp