ブログ

[Unity] SpriteAtlas を AddressableAssetSystem で使用する

背景

  • スプライトアトラスとアセットバンドルの組み合わせの解説はある
  • が、AddressableAssetSystem(以下、AAS)での解説はあまりないので記事にした
  • 環境:Unity 2020.3.23, Addressables 1.19.19

方法

元スプライトもスプライトアトラスも両方がローカルアセットの場合

ローカルアセットとは、AAS のリモートアセットでなく、アプリ本体(apk, ipa)に入っているアセットのこと。

エディタのProjectヒエラルキーにて、右クリックで Create - 2D - SpriteAtlas でスプライトアトラスを新規作成し、下図のように設定する。

SpriteAtlas_1

  • Allow Rotation, Tight Packing のチェックを外す
  • Objects for Packing に元となるスプライトやフォルダをドラッグ&ドロップ
  • Pack Preview でパッキング確認

AAS を使用している状態からスプライトアトラスを使用している状況なので、元スプライトは Addressable になっている想定。

スプライトアトラスの方は Include in Build が ON になっていれば、Addressble にしなくても問題ない。

このままアプリビルドすれば、AAS でも問題なくスプライトアトラスが有効になっている。

元スプライトがリモートアセットの場合

1. スプライトアトラスの設定

下図のように設定する。

例として、Assets/Main/UI/Textures/SpriteAtlas/RemoteAsset/SpriteAtlas_test.spriteatlas とする。

SpriteAtlas_3

  • Addressable を有効にして、AAS にてリモートアセットとする
    • 元スプライトと同じ AASグループ にしておけばOK
    • SpriteAtlasManager.atlasRequested(後述)で使用するため
  • Include in Build を無効にする
    • さもないと、せっかくリモートアセットにした元スプライトがアプリ本体(apk, ipa)に含まれてしまう

2. SpriteAtlasManager.atlasRequested の設定

ランタイムで atlasRequested を設定しないと、元スプライトを Addressables.LoadAssetsAsync したときに SpriteAtlasManager.atlasRequested wasn't listened to while スプライトアトラス名 requested. なる警告が出力されてしまう。

LoadAssetsAsync よりも前に、SpriteAtlasManager.atlasRequested += AtlasRequested が実行されるようにする。

スクリプトは以下。(スプライトアトラスが Request されたときに、それのロード方法を渡している)

using UnityEngine.U2D;

private void OnEnable()
{
    SpriteAtlasManager.atlasRequested += AtlasRequested;
}

private void OnDisable()
{
    SpriteAtlasManager.atlasRequested -= AtlasRequested;
}

private async void AtlasRequested(string tag, System.Action<SpriteAtlas> atlasAction)
{
    var handle = Addressables.LoadAssetAsync<SpriteAtlas>($"Assets/Main/UI/Textures/SpriteAtlas/RemoteAsset/{tag}.spriteatlas");
    await handle.Task;

    if (handle.Status == AsyncOperationStatus.Succeeded)
    {
        atlasAction.Invoke(handle.Result);
    }
}

 

3. スプライトアトラスから GetSprite して使用

元スプライトの LoadAssetsAsync の完了後に、以下のようにスプライトアトラスから元スプライトを取得する。

Sprite sprite = null;
foreach (var spriteAtlas in Resources.FindObjectsOfTypeAll<SpriteAtlas>())
{
    if (spriteAtlas.name == "SpriteAtlas_test")
    {
        sprite = spriteAtlas.GetSprite("元スプライト名");
    }
}

 

-ブログ

© 2022 墾田ええねん! Powered by AFFINGER5