4
3

【Unity】リソースデータ (Resources/StreamingAssets/AssetBundle) 読み込みについてまとめてみた

Last updated at Posted at 2022-01-31

リソースデータについて

  • Unity プロジェクトに「画像」「3Dモデル」「音声」「動画」など、ファイルサイズが大きいアセットが含まれる
  • ユーザーに届ける方法は大きく分けると2つ
    • 全アセットをビルドに含める
    • DLC(ダウンロードコンテンツ)としてゲーム内(アプリ内)でダウンロードさせる

Resources

  • 旧来の Unity 開発で頻繁に利用されていたアセットの動的読み込みを行うための仕組み
    • Resources という名前がついたフォルダは、ビルド時にアプリのバイナリに同梱される
    • Resources.Load("path/to/asset") といったAPIから読み込みが行える
  • 現在は非推奨
    • メモリ管理が難しくなる
    • アプリの起動時間が長くなる
    • リソースを特定のプラットフォームにのみ配信するなどの対応ができない

Resources を使ってもよいケース

  • プロトタイプ開発時
  • アプリが立ち上がっている間常駐するリソース
  • メモリをあまり使わない場合
  • プラットフォーム間でリソースを切り替える必要がない場合

StreamingAssets

  • アセットを変換しないでそのままアプリに持っていく仕組み
    • バイナリとして保存するのでデシリアライズが必要
  • プラットフォームごとに配置されるフォルダは異なり、 Application.streamingAssetsPath で取得できる
    • Unity Editor、Windows、Linux、PS4、Xbox、Switch は Application.dataPath + "/StreamingAssets"
    • macOS は Application.dataPath + "/Resources/Data/StreamingAssets"
    • iOS は Application.dataPath + "/Raw"
    • Android は圧縮された APK/JAR ファイル "jar:file://" + Application.dataPath + "!/assets"
  • Android の場合は UnityWeRequest を使ってロードする

StreamingAssets を使ってもよいケース

  • ビルド済みの AssetBundle を格納する
    • AssetBundle は変更しなければビルドし直し不要のため、ビルド時間の削減
    • ビルド前処理に buildTarget に指定されたプラットフォームの AssetBundle のみを StreamingAssets に配置する必要がある
  • プラットフォームごとに変換が不要なアセットの読み込み

AssetBundle

  • Import済アセットのバイナリデータを固めたモノ
    • DLCとしてダウンロードすることで、ビルドに含まれないリソースを追加読み込みできる
  • AssetBundle として使えるアセットは
    • 画像
    • オーディオファイル
    • フォント
    • Scene
    • Prefab
    • フォルダ
      • C#スクリプトを固めることはできない
  • 通常の AssetBundle と Streamed AssetBundle(Streamed Scene AssetBundle) に分類できる

通常の AssetBundle

  • Scene を除く任意の Asset を固めた AssetBundle のこと
    • 1つ以上の Asset が固められたバイナリデータをファイルとして出力したもの
      • 内部的には Lz4 などの圧縮アルゴリズムを用いて圧縮されたファイル

Streamed Scene AssetBundle

  • Scene そのものを AssetBundle として固めたもの
    • Scene 内の GameObject から参照されているアセットも一緒に固められる
  • 圧縮などの仕組みは通常の AssetBundle と変わらない
  • AssetBundle を Load した時点で SceneManager からアクセス可能になる

AssetBundle でできること

  • DLC としてアセットを動的ロードする
  • バリエーションを持たせる
    • 複数のプラットフォーム、国、地域に配信するときなど、リソースデータにバリエーションをもたせたい
    • AssetBundle Variants 機能を使う
  • 任意の粒度でまとめる
    • 設定した AssetBundle Name 単位でグルーピングされる
    • APIを叩いてグルーピング可能
  • 依存関係を構築する

Addressable Asset System

  • アドレスを指定することでリソースデータをロードできる機能
    • アドレスは Asset ごとに付けることができる任意の名前
  • ローカルのデータか、リモートから AssetBundle をロードするか設定ひとつで変更できる
    • 呼び出し側は同じインターフェースでロードできる

使い方

  • Unity2019.3以上ならば Package Manager から Addressables をインストールすることで使用可能
    image.png
  • Window > Asset Management > Addressables > Settings を選択すると。 AddressableAssetsData フォルダが作成される
    image.png
    image.png
  • Addressable にチェックを入れることで、Addressable の管理対象になる
    • Addressables Group に追加される
      image.png
      image.png

フォルダ構成

アセット 内容
AddressableAssetSettings.asset ・プロジェクトのAddressableの設定が保存されている
AssetGroups/ ・Groupに属しているアセットのGUIDやLabel情報などを管理
AssetGroups/Built In Data.asset ・Resources や Scene in Buildに関わる情報を管理
AssetGroups/Default Local Group.asset ・Playerビルドに含めるアセットを管理
・初期状態に作成される
Schemas/ ・Groupの詳細な設定を管理
・GroupごとにSchemasが配置される
AssetGroupTemplates/ ・Groupの新規作成時につかうテンプレ
・新規でGroup Templeteを作成したときは AddressableAssetSettings に追加しなければならない
DataBuilders/ ・ビルド、エディタ再生時に使用される設定
・AssetBundleのビルド方法を定義したScriptableObjectが配置される
DefaultObject.asset ・AddressableAssetSettings.assetの場所を示すScriptableObject

※ DataBuilders や AssetGroupTemples はあまり編集しない

AssetBundle をビルドする

  • 新規の場合h AddressableGroups で、 Build > New Build > Default Build Script を選択する
    • すでにビルド済みの AssetBundle を更新する場合は Update a Previous Build
      image.png
  • Build される場所は以下で設定できる
    • LoadBuildPath: Library/com.unity.addressables/[BuildTarget](デフォルト)
      • Playerビルド時に一時的に StreamingAssets にコピーされることで Player ビルドに同梱される
    • RemoteBuildPath: ServerData/[BuildTarget](デフォルト)
      • プロジェクトルート直下に作成される ServerData 以下に作成された AssetBundle を RemoteLoadPath のURLに対応するようにアップロードする必要がある
        image.png

AssetBundle を読み込む

  • 通常はアプリ起動時に自動的に Addressable の初期化処理が実行される
  • 何らかの理由でスクリプトから初期化、実体化したい場合は
    • Addressables.LoadAssetAsync() してから Instantiate() する
    • 直接 Addressables.InstantiateAsync() する
// Load してから Instatiate()
var gameobject = await Addressables.LoadAssetAsync<GameObject>("Assets/Prefabs/Cube.prefab");
var obj = Instantiate(go);

// 直接 Instatiate()
Addressables.LoadAssetAsync<GameObject>("Assets/Prefabs/Cube.prefab");

参考文献

4
3
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3