💎

Addressables で ScriptableObject からデータをロードする

2024/03/10に公開

はじめに

Unity の AddressablesScriptableObject を用いて、ゲーム内に定義したアセットを任意のタイミングでロードするフローを確認します。

動作環境

  • Unity 2022.3.20f1
  • Addressables 1.21.20

Addressables とは

Unity におけるアセット管理システムであり、 Package Manager からインストール出来ます。事前にアセットをロード可能な対象としてグルーピングしておくことで、グルーピングされたアセットの中からいつでもアセットをロードし使うことが出来るようになります。(アセットには、ゲーム画像やテクスチャ、マテリアル、ゲーム音源など様々なものがあります)

https://unity.com/ja/how-to/simplify-your-content-management-addressables
https://docs.unity3d.com/Packages/com.unity.addressables@1.21/manual/index.html

ScriptableObject とは

ゲーム内のアイテムや敵パラメータ等のデータを作るために使うことが出来るシリアライズ可能なクラスです。アイテムや敵パラメータといったデータを ScriptableObject クラスからアセット化しておくことで、先に挙げた Addressables を介してロードすることが出来ます。

https://unity.com/ja/how-to/architect-game-code-scriptable-objects

動作確認

Addressables のインストール

Unity の Package Manager を介して、Addressables をインストールします。

Package Manager を開き、Packages: Unity Registry になっている状態で Addressables を検索すると以下のようなパッケージが表示されるかと思います。これが表示されれば、右上に「Install」といったボタンが出ていると思うので、そこからインストールが可能です。

インストールが完了したら、Unity Editor の Window から以下の Groups をクリックします。

Groups クリック後に表示されるウィンドウにある Create Addressables Settings をクリックします。これを行うと、Assets フォルダ直下に AddressableAssetsData という名前のフォルダが自動的に生成されます。このフォルダ内に Addressables に関する設定が格納されているようです。

ScriptableObject からアセットを作成

ScriptableObject を使ってデータアセットを作成します。

今回は、カードゲームにおけるカードデータをアセットとして管理することを想定し、以下のような CardAsset クラスを ScriptableObject で定義します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


[CreateAssetMenu(fileName = "CardAsset", menuName = "MyAssets/CardAsset")]
public class CardAsset : ScriptableObject
{
    public string cardID;
    public string cardName;
    public int cardCost;
    public int cardPower;
    public int cardLife;
}

クラス定義が出来たら、Unity Editor 側で以下のようにカードデータをアセットとして作成します。今回は Assets/Scripts/Data/CardAssets/ というフォルダを作り、その中に 3 つのカードアセットを作成してみました。


アセットを Addressables に登録

先ほど作成したカードアセットを Addressables に登録してみます。Addressables へのアセット登録は 1 つずつでもフォルダ単位でも可能です。今回はフォルダごとまとめて登録します。
Project ウィンドウから Assets/Scripts/Data/CardAssets/Addressables Groups にドラッグ&ドロップすればOKです。

また登録後、シンプルな識別子でアセットをロード出来るようにするために、Simplify Addressable Names をクリックしておきましょう。

こうすると、今回取得したいアセットに対して CardAssets/card_1.asset というようなアドレスでアクセス可能となります。

アセットをロードする Script を作成

登録したアセットを Script から取得してみます。
以下の Script を作成しました。

AddressablesTest.cs

using System.Collections;
using System.Collections.Generic;
using Frontier.Data;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;


public class AddressablesTest : MonoBehaviour
{
    private PureAssetLoader pureAssetLoader;

    private void Awake()
    {
        pureAssetLoader = new();
    }

    private void Start()
    {
        pureAssetLoader.Load("card_1.asset");
    }
}

PureAssetLoader.cs

using System.Collections;
using System.Collections.Generic;
using Frontier.Data;
using UnityEngine;
using UnityEngine.AddressableAssets;

public class PureAssetLoader
{
    private const string BASE_ADDRESS = "CardAssets";

    async public void Load(string assetAddress)
    {
        string _address = $"{BASE_ADDRESS}/{assetAddress}";
        CardAsset cardAsset = await Addressables.LoadAssetAsync<CardAsset>(_address).Task;

        Debug.Log(cardAsset.cardName);

        Addressables.Release(cardAsset);
    }
}

空のオブジェクトを作り、AddressablesTest.cs をそこに Add します。
AddressablesTestPureAssetLoaderLoad メソッドを呼び出し、引数で指定されたアドレスに対応するカードアセットを取得します。Generics により CardAsset の型情報を与えられるため、Addressables.LoadAssetAsync の返り値は自身で定義した CardAsset のインスタンスとして受け取ることが出来ます。

実行

この状態で Play Mode に入ると、CardAssets/card_1.asset のアセットが読み込まれ、その cardName がログ出力されるかと思います。

終わりに

Addressables を使うことで、プロジェクト内の好きなアセットを一元管理し、好きなタイミングでロードできるため便利に感じました。今回は ScriptableObject のアセットを手動で作成・登録するフローにより動作検証を行いましたが、例えば、外部からアセットリストを取得 -> リストにあるアセットを全て Addressables に登録 -> 登録したアセットをまとめて取得、といった使い方も面白そうですね。

また今回取り上げませんでしたが、 Addressables は外部URLにあるアセットを直接取得することも出来るようなので、Unity プロジェクト内を変更することなく、外部リソースだけ更新といった使い方も出来るみたいです。便利ですね。

参考

https://unity.com/ja/how-to/simplify-your-content-management-addressables
https://docs.unity3d.com/Packages/com.unity.addressables@1.21/manual/index.html
https://unity.com/ja/how-to/architect-game-code-scriptable-objects
https://www.hanachiru-blog.com/entry/2022/03/21/120000
https://light11.hatenadiary.com/entry/2019/12/26/225232

Discussion