【Unity】Addressablesの使い方!Unityでのリソース管理を最適化しよう

Addressablesの使い方 Unity

今回はUnityでのリソース管理・最適化に関する話題で、タイトルの通り

Addressable Asset Systemの使い方

を一通りまとめてみるという内容になっています。

Unityで一定以上の規模のゲームを作っていると

  • アセットを動的にロード・アンロードしたい
  • ゲーム内容の一部をダウンロードコンテンツにしたい
  • メモリ管理をより厳密に行いたい

といった要望が出てくることがあります。このようなときに非常に便利なのがUnityのパッケージとして提供されている「Addressable Asset System(通称:Addressables)」なのですが、正直なところ

  • そんなの聞いたことないよ
  • なんか聞いたことはあるけど使ったことはないなぁ
  • 興味はあるけど使い方がよく分からん!

という方がほとんどなのではないでしょうか?

そこでここではこのAddressablesについて、概要~基本的な使い方までを丁寧にご説明しますね。

Addressable Asset System(通称Addressables)とは?

はじめに「Addressablesとは?」という点からお話ししようと思います。このシステムについての詳しい概要はUnity公式ページをご覧いただきたいのですが…

Addressable を使用してコンテンツ管理を簡略化する
Learn how the Addressable Asset System can simplify your content management at both edit and runtime so your game’s initial and updated releases are smoother an...

まあ簡単に言うと「アセットをアドレスによって管理し、任意の場所から動的にロードできるシステム」となっています。

ただこれだけだとピンとこない方も多いかと思いますので、ここでは他のリソース管理方法と比較したときのAddressablesのメリットについて解説します。

前提知識:Unityでリソース管理を行うための2つの方法

まず前提知識として、執筆時点のUnityにはリソース管理を行うための次の2つの方法があります。

  1. Resourcesフォルダ
  2. Addressables

Resourcesフォルダ

一つ目は昔からあって初心者の方にもわかりやすいResourcesフォルダです。これはフォルダを作ってその名前を「Resources」にするだけで、そこに入れたアセットをスクリプトから動的にロードできるようになるのでとても簡単に使うことができます。

ただしこのResourcesフォルダは乱用すると問題の元になりやすい性質があり、Unity側も「使わないのが一番」と明言しています。具体的にどのような問題が起きるのかについては下記の記事でご説明しているのですが…

【Unity】できれば「使わない方がいい」Unityの機能ワースト3
Unityを使っていると、ある機能についてよく調べたときに公式が「その機能は使うな」みたいなことを平気で言っていることがあります。個人的には機能を提供しておいてそれはねーだろ…と思うわけですが、Unityでは「あまり良くない機能だが、分かり...

簡単に言うとゲームのサイズが肥大化したり、メモリを余計に食うようになったりするので割と危険をはらむ機能となっているというわけです。なので小規模な練習作とかならともかく、まともなゲームを作るうえではこの機能は使うべきではありません。

Addressables

次に二つ目は今回の主役であるAddressablesです。こちらは少し抽象的でイメージしづらいのですが、端的にResoucesフォルダと比較した場合のメリットを挙げると次のようなものがあります。

  • 使用するアセットだけをゲームに組み込むことができる。必要に応じてダウンロードコンテンツのように外部からロードすることも可能
  • メモリをより厳密に管理することができる

Addressablesは「必要なアセットを必要な時だけロードする」ことを意識した作りになっているので、ゲームに余計なアセットを組み込む必要がなくなったり、消費メモリをより少なくできたりするのが大きなメリットです。

Resoucesフォルダを使った場合はかなり大雑把なリソース管理となるのですが、Addressablesの場合はリソースを厳密に管理できるので膨大なアセットを使うことになる大規模開発では必須となるでしょう。また、たとえ個人開発ゲームのような小規模ゲームの場合であっても

  • ダウンロードコンテンツを用意したい
  • より多くのリソースを使う3Dゲームを開発したい

といった場合はかなり役に立つと思います。

Addressablesの基本的な使い方

では概要やメリットについてご理解頂いたところで、ここからAddressablesの基本的な使い方についてご説明していきます。

導入方法

まず導入方法ですが、Unityパッケージマネージャから簡単にインストールできます。

Addressables インストール方法

アドレスのつけ方

次に、アセットをAddressablesで扱うためにはアドレスをつける必要があります。これもやり方は簡単で、任意のアセットやシーンをインスペクターで表示して上の方にある「Addressable」にチェックを入れるだけです。

Addressables アドレスのつけ方

デフォルトだとアセットやシーンへのパスがそのままアドレスとして設定されます。ただしそれだと階層が深いアセットの場合はべらぼうに長いアドレスになってしまい不便なので、適当な名前に変更することもできます。

また、「Addressable」チェックボックスをONにした後に出現する「Select」ボタンを押すとAddressable Groupウィンドウが開き、Addressablesで管理しているアセットのグループが表示されます。

Addressables Group ウィンドウ

アセットの所属グループはこのウィンドウで変更できるほか、任意のアセットを右クリックするとメニューが表示され、新しいグループを作ったりアドレスを簡略化したりすることができます。

C#スクリプトからアセットをロード/アンロードする方法

さて、ここまで準備できたらC#スクリプトからアセットを動的に読み込めるようになっているので実際に試してみましょう。

アセットのロード方法は

  1. アドレスを直接指定する
  2. AssetReferenceをシリアライズして使う

の2通りがありますが、基本的には2番目の方法がおすすめです。例えばAddressablesに登録したプレハブをInstantiateする場合のサンプルスクリプトは次のとおり。

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class AddressablesTest : MonoBehaviour
{

    [SerializeField]
    AssetReference reference;

    // アンロードに必要
    AsyncOperationHandle handle;

    void Start()
    {
        LoadAsset();
    }

    void Update()
    {
        if (Input.GetButtonDown("Jump"))
        {
            UnloadAsset();
        }
    }

    void LoadAsset()
    {
        handle = reference.InstantiateAsync();
    }

    void UnloadAsset()
    {
        if (!handle.IsValid())
        {
            return;
        }

        Addressables.ReleaseInstance(handle);
    }

}

基本的には非同期でのロード/アンロードになるので、AsyncOperationHandleという型の変数を用意しておいて

  • Instantiateの時にロードし、戻り値のAsyncOperationHandleをキャッシュ
  • アンロードにはキャッシュしておいたAsyncOperationHandleを渡す

というような形になります。ちなみにAsyncOperationHandleをコルーチンに使えばロードが処理が終わるまで待つ、といったこともできます。

おわりに

以上、Addressablesの概要から基本的な使い方までは一通りご紹介しました。

Addressablesは一見すると分かりにくいシステムで少し取っつきにくいかもしれませんが、使いこなせると非常に便利なのでもうResourcesフォルダには戻れなくなるでしょう。ぜひ上記を参考にして使ってみて頂ければと思います。

この記事がUnityでのゲーム開発のお役に立てば幸いです。