YAMADA TAISHI’s diary

ゲームについてとか私の日記とか。このブログのあらゆるコードは好きにどうぞ。利用規約があるものは記事内のGitHubのRepositoryのリンクで貼られていると思うので、そちらを参照ください。

【後編】UnityのAddressableを個人制作で使いこなす

こんにちは、やまだたいし(https://twitter.com/OrotiYamatano)です。
コチラの記事の後編です。

orotiyamatano.hatenablog.com

目次


前回まで


前回はAddressableの概要とインストール、
AddressableAssetSettingsの設定一覧を確認しました。

今回は


AddressableAssetSettingsの実践的な設定から、実際のアセットの準備、ロード処理の実装、そしてビルドまでを解説します。
前回から結構日付が立ってしまったので2.2.2のバージョンを使うことにします。

前回と同様な設定の箇所は割愛します。

AddressableAssetSettingsの実践的な設定


まずDefault Local Groupのデフォルト設定を直接変更します。

Build & Load Paths


ローカルロードをしたいのでLocalを選択します。
リモートの場合はCDNなどのサーバーを用意する必要がありますが、個人開発では基本的にローカルで十分です。

AddressableAssetSettingsの基本設定


  • Profile In Use
    こちらはまだデフォルトしかないはずです。そのままデフォルトを選択します。
    今回はローカルを使うのでBuilt-Inということになります。

  • Diagnostics
    Log Runtime Exceptionsにチェックを付けたままにします。
    開発中はログを取得できた方が問題の特定が容易になるためです。

Catalog設定


カタログはアセットとしてダウンロードすべきアセットを一覧化したものです。
以下の設定を行います:

  • BuildRemoteCatalog: チェックなし
    リモートなら手元を最新化してほしいだろうと思うのでチェックつけると思いますが、今回はローカルなのでなしです。

  • EnableJsonCatalog: チェックなし
    Json形式のカタログを書くかどうかです。デバッグ時には便利ですが、
    実はこのカタログを読むことでユーザーに次の入れられるキャラがバレたみたいな話もあるので、チェックはしないほうが良いでしょう。

  • Internal Asset Naming Mode: Dynamic
    一番どうするか悩みどころですが、今回は推奨のDynamicに挑戦してみることにします。
    FullPathでも良いのですが、リモート&大企業さんの場合はGUIDが良いかもしれません。
    というのも、カタログはネットワークから取得する場合、FullPathだと大規模容量の時にカタログ自体も情報量が多くなりすぎて、
    カタログファイル自体を読むのに時間がかかってしまうからです。

  • Asset Load Mode: Requested Asset and Dependencies
    推奨設定です。必要なアセットとその依存関係のみを読み込むため、メモリ効率が良くなります。

Downloads設定


  • Use Unity WebRequest for Local Assets Bundles: チェックあり
    開発が大規模化したときのことも考えてWebRequest経由で読み込めるように変えておきます。
    そうすることで、今後リモート化したときも同じコードが使い回せます。

  • タイムアウト関連: デフォルト(最大値)
    ローカルでの読み込みなのでタイムアウトは基本的に発生しないため、デフォルトのままで問題ありません。

Build設定


  • Build Addressables on Player Build: Use global Settings
    これは好みによるところがあります。エディターの環境設定に従う形にしておくことで、
    チーム開発時にも統一した設定を使用できます。

  • Strip Unity Version From AssetBundles: チェックなし
    Unityバージョンを含めるかどうかの設定です。ビルドされるアセットの中身がUnityバージョンによって
    変わる可能性があるので、含めた方が安全です。

これらの設定により、ローカルでの利用に最適化しつつ、将来的な拡張性も確保した構成が整います。

カタログとアセット管理の基礎


カタログについて


カタログ(catalog.json)は、Addressableシステムの心臓部とも言える重要なファイルです。
これは単なる目録ではなく、アセットとしてダウンロードすべきアセットを一覧化したものです。 独自で作成することも、分割することも可能です(今回は分割方法については割愛します)。

Addressableは基本的に以下の流れでアセットを読み込みます:

  1. 初期化時にカタログを読み込む
  2. カタログ情報を元に必要なアセットをダウンロード
  3. アセットの依存関係を解決して読み込み

よくあるスマホゲーム起動時の「データダウンロード」画面で行われているのは、
このカタログ情報の取得とそれに基づくアセットのダウンロードです。

Note
カタログはリモートに置く場合もあれば、ローカルに置く場合もあります。
今回はローカルでの利用を想定しています。

アセットの設定方法


さて、アセット設定ができたところで、実際にアセットをAddressableのアセットとして登録します。
しかし、Resourcesが多くなるほど管理が複雑になり、自前での管理は辛い状況になります。

とくに以下のような作業は手作業では限界があります:

  • 大量のアセットへのアドレス割り当て
  • アドレスの一貫性維持
  • 依存関係の管理

そこで、今回はサイバーエージェントさんが公開している「Smart Addresser」を活用します。
これはアドレスの割り振りを自動化してくれる非常に便利なツールです。

詳しい使い方は以下の公式ドキュメントを参照してください:

個人利用でもその恩恵は十分に得られます:

  • アドレスの自動割り振り
  • 一貫性のある命名規則の適用
  • アセット管理の効率化

Smart Addresserの実践的な設定


Window→Asset Management→Addressables→Groupsをクリックし、
Addressable Groups Windowを立ち上げます。

Profileは前回設定したDefaultが設定されているのを確認します。

Window内で右クリックしCreate→New Group→PackedAssetsをクリックすると、

新しいグループが追加されます。

ちなみにAssets>AddressableAssesDataフォルダーの中にある該当名のScriptableObjectが実体となります。

名前はF2で変更可能です。
わかりやすいようにTestに変えておきましょう。

Testの行を選択すると該当のScriptableObjectがProjectWindowで選択され、
InspectorWindowにグループ設定が表示されます。

グループの設定内容


内容については前回解説済みですが、今回は以下のように設定します:

設定の意図は以下の通りです:

  • Build & Load Path: Local
    ローカル読み込みを行うため

  • Asset Bundle CRC: Enabled
    念のためCRCチェックを有効化

  • Include in Catalog Settings

    • Include Addresses in Catalog: チェックあり
      アドレスでの読み込みを行うため
    • Include GUIDs in Catalog: チェックなし
      AssetReferenceを使用しないため
    • Include Labels in Catalog: チェックなし
      ラベルによる管理を行わないため
  • Bundle Mode: Pack Separately
    個別に読み込みたいアセットが多いため

Smart Addresserでの管理設定


Window>SmartAddresser>LayoutRuleEditorでLayoutRuleEditorWindowを開きます。

追加したグループのControlにチェックを入れ、Smart Addresserでの管理下に置きます。
そして、どのようなアセットをアドレス管理にするかを決めるため、指定したグループのAssetsGroupsにObjectFilterを追加します。

Included Assetsを選択し、実際にダウンロード設定したいAssets配下のフォルダーを指定します。

AssetProviderにはAssetsPathを指定します。
(fileNameなどでもいいですが、名前が重複することもありえるのでAssetsPathを推奨します)

アドレス割り当ての自動化


アドレス割り当てのタイミングは、コードで制御することも可能ですが、
今回はProjectSettingsのSmartAddresserのPrimaryDataに該当のレイアウト設定を指定することで、
該当フォルダーに新しくデータをインポートする際に自動でアドレス割り振りされるようにします。

これで設定は完了です。

エディターでの動作確認


実装したコードを使って、エディター上で設定が正しく機能しているか確認しましょう。

まず、Window→Asset Management→Addressables→Groupsから、
Tools→Play Mode Script→Use Asset Databaseを選択します。
これにより、エディター上でアセットの読み込みをテストできます。

また、Window→Analysis→Profilerを開き、Addressablesモジュールを有効にすることで、
ロード状況やメモリの使用状況をリアルタイムで確認できます。

Note
エディターでの確認時は、アセットのビルドは不要です。
アセットデータベースから直接読み込むため、設定の変更をすぐに確認できます。

もし読み込みに失敗する場合は、以下を確認してください:

  • アセットが正しくグループに割り当てられているか
  • アドレスが正しく設定されているか
  • 指定したパスが正しいか

エディターでの動作確認が完了したら、次はアセットのビルドに進みます。

アセットのロード方法


基本的なロード方法


Addressablesでのアセットロードは非同期処理として実装します。
実際のロード処理は以下のGistで公開しているコードを利用します:

このユーティリティクラスには以下のような特徴があります:

  1. ハンドル管理の自動化

    • 読み込んだアセットのハンドルを自動的に管理
    • 同じアセットの重複ロードを防止
  2. メモリリークの防止

    • IDisposableの実装によるリソース解放の保証
    • 使用していないハンドルの適切な解放
  3. エラーハンドリング

    • 初期化時のエラー処理
    • キャンセル処理のサポート

実装例


実際の使用例を示します:

using UnityEngine;
using UnityEngine.UI;
using System;
using System.Threading;
using Cysharp.Threading.Tasks;

public class SampleLoader : MonoBehaviour
{
    [SerializeField] private Image _image;
    private CancellationTokenSource _cts;

    private async void Start()
    {
        _cts = new CancellationTokenSource();

        try
        {
            await AddressableUtil.InitAsync();
            await LoadAssetAsync(_cts.Token);
        }
        catch (Exception ex)
        {
            Debug.LogError($"Addressablesの処理に失敗: {ex}");
        }
    }

    private async UniTask LoadAssetAsync(CancellationToken cancellationToken = default)
    {
        try
        {
            var sprite = await AddressableUtil.LoadAssetAsync<Sprite>(
                "Assets/MyProject/ResourceAssets/Addressable/me.png",
                cancellationToken
            );
            _image.sprite = sprite;
        }
        catch (OperationCanceledException)
        {
            Debug.Log("アセットのロードがキャンセルされました");
        }
        catch (Exception ex)
        {
            Debug.LogError($"アセットのロードに失敗: {ex}");
        }
    }

    private void OnDestroy()
    {
        _cts?.Cancel();
        _cts?.Dispose();
    }
}

このように分けることで:

  • 初期化とロード処理が明確に分離される
  • 必要に応じてロード処理だけを再実行できる
  • 他の初期化処理と順序を調整しやすい

という利点があります。

なお、このサンプルでは初期化直後にロードしていますが、 ボタンクリック時やシーン遷移後など、任意のタイミングで LoadAssetAsyncを呼び出すことも可能です。

メモリ管理

Addressablesでは、ロードしたアセットの解放を明示的に行う必要があります:

// アセットの解放
Addressables.Release(handle);

Event Viewerによるデバッグ


Addressablesのデバッグには、Event Viewerという機能が用意されています。
バージョンによって利用方法が異なりますので、それぞれの方法を説明します。

2.2.2以降の場合

2.2.2からはUnityのプロファイラーに統合されています。
Window→Analysis→Profilerを開き、Addressablesモジュールを有効にすることで利用できます。

1.x系の場合


1.x系では、パッケージマネージャーからEvent Viewerを明示的に有効化する必要があります。
その後後、以下の設定を行います:

  1. AddressableAssetSettingsのインスペクターで「Send Profiler Events」を有効化
  2. 新しいコンテンツビルドを作成

その後、Window→Asset Management→Addressables→Event Viewerから利用できます。

共通の機能


Event Viewerでは:

  • アセットのロード時間
  • メモリ使用量
  • ロードの成功/失敗
  • 重複ロードの検出

などを確認できます。

とくに開発中は、このツールを使ってメモリリークやロードの問題を早期に発見することをオススメします。

アセットのビルド


エディターでの動作確認が完了したら、実機やビルド環境で使用するためのアセットビルドを行います。

Window→Asset Management→Addressables→Groupsから、
Build→New Build→Default Buildを選択します。

ビルドが成功すると、Library/com.unity.addressables/にアセットバンドルが生成されます。
このビルドは、アセットの追加や変更を行った際に実行する必要があります。

また、Play Mode ScriptをUse Existing Buildに変更することで、
エディター上でもビルドしたアセットバンドルを使用した動作確認ができます。

注意
アセットをビルドせずにアプリケーションをビルドすると、
ランタイムでアセットが見つからずエラーになります。
必ずアセットのビルドを行ってからアプリケーションをビルドしてください。

ビルドの確認


ビルドが完了したら、Play Mode ScriptをUse Existing Buildに変更して動作確認を行います。

Window→Asset Management→Addressables→Groupsから、
Play Mode Script欄をUse Existing Buildに変更します。

これにより、エディター上でもビルドされたアセットバンドルを使用した動作確認が可能になります。

実際のビルドファイルは以下の場所に生成されています:

  • Library/com.unity.addressables/ - ビルド時の中間ファイル
  • ServerData/ - リモートビルド用のファイル
  • Assets/StreamingAssets/aa/ - ローカルビルド用のファイル

今回はローカルビルドなので、Assets/StreamingAssets/aa/内のファイルが実際に使用されます。

ビルドしたアプリケーションでは、このStreamingAssets内のファイルからアセットがロードされます。 エディター上でUse Existing Buildを選択することで、同様の動作を確認できます。

もし動作に問題がある場合は、以下を確認してください:

  • アセットが正しくグループに割り当てられているか
  • 最新のアセットがビルドされているか
  • アドレスが正しく設定されているか
  • StreamingAssetsフォルダーが存在し、必要なファイルが含まれているか

実機での確認


エディター上での動作確認が完了したら、実際にビルドして動作を確認します。

  1. まずAddressablesのビルドを行います(上記の手順通り)

  2. File→Build Settings(Ctrl+Shift+B)を開き、Build And Runを実行

重要
必ずAddressablesのビルドを先に行ってください。
アプリケーションのビルド時にStreamingAssetsフォルダーの内容が
実行ファイルと同じ場所にコピーされます。

ビルドしたアプリケーションを実行し、以下を確認します:

  • アセットが正しくロードされるか
  • ロード時のパフォーマンスは問題ないか
  • メモリの使用量は想定通りか

もし問題が発生した場合は、Development Buildを有効にして
ログを確認することで原因の特定が容易になります。

ビルドとデプロイメント


ビルドファイルについて


Addressablesでビルドされたアセットは以下の場所に生成されます:

  • Library/com.unity.addressables/ - ビルド時の中間ファイル
  • ServerData/ - リモートビルド用のファイル
  • Assets/StreamingAssets/aa/ - ローカルビルド用のファイル

今回はローカルビルドを使用しているため、Assets/StreamingAssets/aa/内のファイルが実際に使用されます。

アプリケーションビルド時の注意点


重要
必ずAddressablesのビルドを先に行ってください。
アプリケーションのビルド時にStreamingAssetsフォルダーの内容が 実行ファイルと同じ場所にコピーされます。

手順:
1. まずAddressablesのビルドを実行
2. File→Build Settings(Ctrl+Shift+B)からアプリケーションをビルド

もし問題が発生した場合は、Development Buildを有効にして
ログを確認することで原因の特定が容易になります。

ちなみにunityroomで動かしたい場合はJuhaさんの↓などがおすすめです。 zenn.dev

まとめ


今回は以下の内容を解説しました:

  • Addressablesの実践的な設定方法
  • Smart Addresserを使ったアセット管理
  • 基本的なアセットロードの実装

個人開発でもAddressablesを活用することで、アセット管理がより効率的になります。
とくにSmart Addresserとの組み合わせは、開発効率を大きく向上させてくれるでしょう。
以上やまだたいしでした。