しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

Unity の Addressables でリモートアセットの取得先を切り替える【失敗】

※ これは 2022/07/28 時点の Unity 2022.1.11f1 Addressables v1.20.3 Windows 11 の情報です

最新版では動作が異なる可能性がありますのでご注意ください

前回に引き続き Addressables で、今回はリモートアセットの取得先エンドポイントを切り替えてみたい

アセットとして うちのこメーカー で作成した下記画像2枚を使ってみる

切り替える画像

Addressables Profiles のウィンドウを見る限り、Remote.LoadPath に動的な変数を埋め込めばエンドポイントを切り替えられるのではないか?という予想

末尾を切り替えられる?

まずは Assets/Sprites/cat.png の画像を差し替えて、ServerData/StandaloneWindows64 の生成済みのファイルを削除したのち Addressables Groups の [Build] - [New Build] - [Default Build Script] でアセットバンドルのビルドを行う

画像のビルド

ビルドが終わったら ServerData/StandaloneWindows64 にできたカタログ、ハッシュ、アセットバンドルを一方のエンドポイントにコピーする

カタログ、ハッシュ、アセットバンドルの配備

同じように Assets/Sprites/cat.png の画像を差し替えて、ServerData/StandaloneWindows64 の生成済みのファイルを削除したのち Addressables Groups の [Build] - [New Build] - [Default Build Script] でアセットバンドルのビルドを行う

できたカタログ、ハッシュ、アセットバンドルをもう一方のエンドポイントにコピーする

画像を差し替えて再度ビルド

次に下記のような static な変数持ちクラス Cat.cs を用意、最初に Remote.LoadPath に埋め込んでいた変数用に使う

public static class Cat
{
    /// <summary>
    /// ねこの名前
    /// </summary>
    public static string Name { get; set; } = "Cafe";
}

また、Test.cs を下記のように変更

カタログから取得した IResourceLocator.Locate() を使って Assets/Sprites/cat.png のアドレスのリモート取得先 URL を確認しているのがポイント

using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    [SerializeField]
    private Image thumbnailImage = null;

    private AsyncOperationHandle<Sprite> handle = default;

    public async void Start()
    {
        // Addresables 初期化
        await Addressables.InitializeAsync().Task;

        await SetCatAsset("Cafe");
    }

    private async Task SetCatAsset(string catName)
    {
        Cat.Name = catName;

        // リモートカタログに変更があれば更新する
        var catalogs = await Addressables.CheckForCatalogUpdates(true).Task;
        if (catalogs != null && catalogs.Count > 0)
        {
            var locators = await Addressables.UpdateCatalogs(catalogs, true).Task;

            // リモートアセットの取得先を確認
            if (locators[0].Locate("Assets/Sprites/cat.png", typeof(Sprite), out var locations))
            {
                // リモートアセットの URL は Dependencies に入っている
                foreach(var location in locations[0].Dependencies)
                {
                    UnityEngine.Debug.Log($"--------------> uri={location.InternalId}");
                }
            }
        }

        // すでにハンドルがあったら解放
        if (this.handle.IsValid())
        {
            Addressables.Release(this.handle);
        }

        // Addressables 経由で Sprite を読み込んで表示
        this.handle = Addressables.LoadAssetAsync<Sprite>("Assets/Sprites/cat.png");
        this.thumbnailImage.sprite = await this.handle.Task;
    }

    /// <summary>
    /// Mocha ボタン押下イベントハンドラ
    /// </summary>
    public async void OnMochaButtonClicked()
    {
        await SetCatAsset("Mocha");
    }

    public void OnDestroy()
    {
        // いらなくなったら handle を Release する
        Addressables.Release(this.handle);
    }
}

これでお試し・・・実行して Mocha ボタンを押下すると

切り替わらない!

切り替わらない!

ログも Cafe の URL しか出てないということは、カタログが更新されてない判定

・・・どうやら Remote.LoadPath に動的な変数を埋め込んでも、評価されるのは Addressables.InitializeAsync() のタイミングだけで、そのあとに変数値を書き換えても無視されるらしい