ゲーム開発
Unity
UnrealEngine
C++
Blender
ゲーム数学
ゲームAI
グラフィックス
サウンド
アニメーション
GBDK
制作日記
IT関連
ツール開発
フロントエンド関連
サーバサイド関連
WordPress関連
ソフトウェア設計
おすすめ技術書
音楽
DTM
楽器・機材
ピアノ
ラーメン日記
四コマ漫画
その他
おすすめアイテム
おもしろコラム
  • ゲーム開発
    • Unity
    • UnrealEngine
    • C++
    • Blender
    • ゲーム数学
    • ゲームAI
    • グラフィックス
    • サウンド
    • アニメーション
    • GBDK
    • 制作日記
  • IT関連
    • ツール開発
    • フロントエンド関連
    • サーバサイド関連
    • WordPress関連
    • ソフトウェア設計
    • おすすめ技術書
  • 音楽
    • DTM
    • 楽器・機材
    • ピアノ
  • ラーメン日記
    • 四コマ漫画
      • その他
        • おすすめアイテム
        • おもしろコラム
      1. ホーム
      2. 20210418_01

      【Unity】AssetBundleを使ってリソースを管理する

      Unity
      2021-04-19

      マイケル
      マイケル
      みなさんこんばんは!
      マイケルです!!
      エレキベア
      エレキベア
      おひさクマ〜〜〜〜
      マイケル
      マイケル
      今日は久しぶりのUnity記事!
      AssetBundle を使ってみるぞ!
      エレキベア
      エレキベア
      AssetBundleって何クマ?
      マイケル
      マイケル
      説明しよう!
      AssetBundleとは!!
      AssetBundleとは
      • Unityで読み込める形にアセットを事前にビルドしておくことで
        アプリ外部からアセットをロードできる仕組みのこと!
      エレキベア
      エレキベア
      アプリ本体とアセットを分けることができるということクマ?
      マイケル
      マイケル
      その通り!
      アプリを直接更新せずにアセット更新の運用をすることができるんだ!

      ↑AssetBundleファイルの作成処理

      ↑AssetBundleファイルのロード処理
      エレキベア
      エレキベア
      これは使うのが楽しみクマ〜〜〜

      参考書籍

      マイケル
      マイケル
      AssetBundleの使い方を勉強するにあたり、Unity公式マニュアルの他に、
      下記の書籍を参考にさせていただきました!

      [Unity公式マニュアル]

      [参考書籍]

      マイケル
      マイケル
      こちらの「AssetBundle」の章を参考にしています!
      実践的なサンプルがたくさん載っているので、
      今回の記事を読んで 詳細を知りたくなった方
      他のサンプルが気になる方 は是非読んでみてください!
      エレキベア
      エレキベア
      内容が盛りだくさんだから
      1冊持っていて損はないクマ〜〜〜

      基本的な使い方

      マイケル
      マイケル
      それじゃ早速使っていこう!

      AssetBundleファイルのビルド処理

      マイケル
      マイケル
      まずはAssetBundleファイルのビルド処理から!
      AssetBundleにしたいAssetを選択して、Inspector最下部よりAssetBundle名を入力します!

      ↑AssetBundle名の入力
      マイケル
      マイケル
      AssetBundleを指定したら、ビルド処理を行います!
      ビルドは下記メソッドより行うことができます!
      // ビルド処理
      BuildPipeline.BuildAssetBundles(
          "./AssetBundle01",            // ビルドパス
          BuildAssetBundleOptions.None, // オプション(圧縮、梱包等)
          BuildTarget.iOS               // プラットフォーム
      );
      マイケル
      マイケル
      第一引数にAssetBundleファイルを作成するパス
      第二引数に圧縮方式第三引数にビルドするプラットフォーム
      を指定します!
      マイケル
      マイケル
      圧縮方式とプラットフォームは下記を指定できます!
      用途に応じて設定しましょう!

      ・圧縮方式

      圧縮方式 実装
      LZMA形式 BuildAssetBundleOptions.None
      非圧縮 BuildAssetBundleOptions.UncompressedAssetBundle
      LZ4形式 BuildAssetBundleOptions.ChunkBasedCompression

      ・プラットフォーム(※一部抜粋)

      圧縮方式 実装
      iOS BuildTarget.iOS
      Android BuildTarget.Android
      Windows BuildTarget.StandaloneWindows
      Mac BuildTarget.StandaloneOSX

      ※詳細は下記参照
      アセットバンドルのビルド – Unity スクリプトリファレンス
      BuildTarget – Unity スクリプトリファレンス

      エレキベア
      エレキベア
      いろんなオプションがあるのクマね
      マイケル
      マイケル
      このメソッドを使って、実際にビルドしてみましょう!
      下記スクリプトをEditorフォルダに作成します!
      using System;
      using System.Collections;
      using System.Collections.Generic;
      using System.IO;
      using UnityEngine;
      using UnityEditor;
      
      /// <summary>
      /// AssetBundleビルド用Editorクラス
      /// </summary>
      public class AssetBundleBuild
      {
          /// <summary>
          /// AssetBundleビルド処理(AssetBundle01)
          /// </summary>
          [MenuItem("Assets/AssetBundle01 Build")]
          public static void Build01()
          {
              Build("./AssetBundle01");
          }
      
          /// <summary>
          /// AssetBundleビルド処理(共通)
          /// </summary>
          /// <param name="assetBundleDirectory">AssetBundleファイル作成パス</param>
          private static void Build(string assetBundleDirectory)
          {
              // ディレクトリ作成
              if (!Directory.Exists(assetBundleDirectory))
              {
                  Directory.CreateDirectory(assetBundleDirectory);
              }
              // ビルド処理
              BuildPipeline.BuildAssetBundles(
                  assetBundleDirectory,         // ビルドパス
                  BuildAssetBundleOptions.None, // オプション(圧縮、梱包等)
                  BuildTarget.iOS               // プラットフォーム
              );
              // 終了メッセージ表示
              EditorUtility.DisplayDialog("AssetBundleビルド完了", "AssetBundleのビルドが終わったでやんす。", "承知!");
          }
      }
      
      マイケル
      マイケル
      するとAssetウィンドウに「AssetBundle01 Build」というメニューが追加されるので実行しましょう!

      ↑ビルド処理の実行
      マイケル
      マイケル
      実行すると下記のようにAssetBundleファイルとmanifestファイルが作成されます!

      ↑完了メッセージ

      ↑AssetBundleファイルとmanifestファイルが作成される
      マイケル
      マイケル
      manifestファイルには、ハッシュ値や依存関係といった情報が記載されています!
      手動で処理を行う場合、使うことも多いと思うため覚えておきましょう!
      エレキベア
      エレキベア
      これで準備完了クマ〜〜〜

      AssetBundleファイルのロード処理

      マイケル
      マイケル
      AssetBundleファイルを作成したら、次はロード処理!
      ローカルからのロード処理
      マイケル
      マイケル
      ネットワーク経由でロードするのが一般的だけど、まずはローカルからのロード処理を実装します!
      AssetBundle.LoadFromFile()メソッドでファイルのロード、LoadAsset()メソッドでインスタンスの生成を行うことができます!
      // AssetBundleファイルをロード
      AssetBundle assetBundle = AssetBundle.LoadFromFile("【AssetBundle格納パス】");
      
      // ロードしたAssetBundleファイルからインスタンス生成
      GameObject prefab = assetBundle.LoadAsset<GameObject>("【Asset名】");
      
      エレキベア
      エレキベア
      ローカルからも読み込めるのクマね
      マイケル
      マイケル
      上記メソッドを使って、下記のようなスクリプトを作成します!
      Sceneの管理クラスとしてアタッチしてみましょう!
      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      
      /// <summary>
      /// Test01Scene管理クラス
      /// </summary>
      public class Test01SceneManager : MonoBehaviour
      {
          /// <summary>
          /// 開始処理
          /// </summary>
          void Start()
          {
              // AssetBundleロード処理
              StartCoroutine("LoadAssetBundle");
          }
      
          /// <summary>
          /// AssetBundleロード処理
          /// (ローカルからの取得)
          /// </summary>
          IEnumerator LoadAssetBundle()
          {
              // AssetBundleファイルをロード
              AssetBundle assetBundle = AssetBundle.LoadFromFile("AssetBundle01/char_prefab");
              if (assetBundle == null)
                  yield break;
              
              // ロードしたAssetBundleファイルからインスタンス生成
              GameObject prefab = assetBundle.LoadAsset<GameObject>("Kani_red");
              Instantiate(prefab);
              Debug.Log("カニをロード!!");
              
              // マウスクリックでアンロード
              yield return new WaitUntil(() => Input.GetMouseButton(0));
              assetBundle.Unload(true);
              Debug.Log("カニをアンロード!!");
          }
      }
      
      マイケル
      マイケル
      するとこのようにしっかりとロードできていることが分かります!
      使い終わったら、assetBundle.Unload()メソッドでアンロードしましょう!
      (※上記処理ではマウスクリックでアンロードしています。)
      エレキベア
      エレキベア
      (シュールクマ・・・。)
      ネットワーク経由でのロード処理
      マイケル
      マイケル
      そして次はネットワーク経由でのロード処理!
      下記のようにUnityWebRequestAssetBundle.GetAssetBundle()メソッドでリクエストを取得して、サーバからダウンロードします!
      
      // Webサーバーからアセットバンドルをダウンロード
      using (UnityWebRequest req = UnityWebRequestAssetBundle.GetAssetBundle("【AssetBundle格納URL】"))
      {
          // Webサーバーからのダウンロード待機
          yield return req.SendWebRequest();
          if (req.result == UnityWebRequest.Result.ConnectionError 
              || req.result == UnityWebRequest.Result.ProtocolError)
          {
              Debug.LogError("エラー:" + req.error);
              yield break;
          }
      
          // AssetBundleファイルをロード後、インスタンス生成
          AssetBundle assetBundle = DownloadHandlerAssetBundle.GetContent(req);
          GameObject prefab = assetBundle.LoadAsset<GameObject>("【Asset名】");
      }
      
      マイケル
      マイケル
      このメソッドを使って実装してみましょう!
      サーバを準備する必要がありますが、Python3がインストールされている環境であれば下記コマンドで立ち上げることができます!
      python -m http.server 8080
      マイケル
      マイケル
      コマンドをプロジェクト配下で実行することで「http://localhost:8080/【AssetBundle格納パス】」でアクセスできるようになります!
      マイケル
      マイケル
      続けてスクリプトを下記に修正しましょう!
      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      using UnityEngine.Networking;
      
      /// <summary>
      /// Test01Scene管理クラス
      /// </summary>
      public class Test01SceneManager : MonoBehaviour
      {
          /// <summary>
          /// 開始処理
          /// </summary>
          void Start()
          {
              // AssetBundleロード処理
              StartCoroutine("LoadAssetBundleNetwork");
          }
      
      ・・・略・・・
      
          /// <summary>
          /// AssetBundleロード処理
          /// (Webサーバからの取得)
          /// </summary>
          IEnumerator LoadAssetBundleNetwork()
          {
              // Webサーバーからアセットバンドルをダウンロード
              using (UnityWebRequest req = UnityWebRequestAssetBundle.GetAssetBundle("http://localhost:8080/AssetBundle01/char_prefab"))
              {
                  // Webサーバーからのダウンロード待機
                  yield return req.SendWebRequest();
                  Debug.Log("http response:" + req.responseCode);
                  if (req.result == UnityWebRequest.Result.ConnectionError 
                      || req.result == UnityWebRequest.Result.ProtocolError)
                  {
                      Debug.LogError("エラー:" + req.error);
                      yield break;
                  }
                  Debug.Log("サーバからAssetBundleを取得!!");
      
                  // AssetBundleファイルをロード後、インスタンス生成
                  AssetBundle assetBundle = DownloadHandlerAssetBundle.GetContent(req);
                  GameObject prefab = assetBundle.LoadAsset<GameObject>("Kani_red");
                  Instantiate(prefab);
                  Debug.Log("カニをロード!!");
                  
                  // マウスクリックでアンロード
                  yield return new WaitUntil(() => Input.GetMouseButton(0));
                  assetBundle.Unload(true);
                  Debug.Log("カニをアンロード!!");
              }
          }
      }
      
      マイケル
      マイケル
      こちらも問題なく読み込めていることがわかります!
      エレキベア
      エレキベア
      (さっきと変わらないクマ・・・。)

      ロード時のテクニック

      マイケル
      マイケル
      以上が基本的な処理となりますが、実用上使うにはまだまだ問題があります!
      その中でもよく使いそうなロード時のテクニックとして2点紹介します!

      複数ファイルのロード処理(依存関係の考慮)

      マイケル
      マイケル
      まずは複数のAssetBundleファイルが存在する場合!
      各Assetにはそれぞれ依存性があり、ロードする順番には気をつけなければならないです!
      マイケル
      マイケル
      manifestファイルより、GetAllDependencies()メソッド依存性のあるAssetを全て取得することができるので、下記のように事前にロードしておきます!
      
      // Manifestファイル
      AssetBundleManifest manifest;
      // ロード済AssetBundleリスト
      Dictionary<string, AssetBundle> loadAssetBundleList = new Dictionary<string, AssetBundle>(); 
      
      /// <summary>
      /// AssetBundleロード処理
      /// (Webサーバから複数ファイル取得)
      /// </summary>
      IEnumerator LoadAssetBundle()
      {
          // AssetBudnle格納URL
          string url = "【AssetBundle格納URL】";
      
          // Manifestファイルをロード
          yield return loadAssetBundle(url, "【AssetBundleフォルダ名】");
          manifest = loadAssetBundleList["【AssetBundleフォルダ名】"].LoadAsset<AssetBundleManifest>("Assetbundlemanifest");
      
          // AssetBundleファイルのロード
          // (Manifestファイルから依存関係のファイルもロードする)
          foreach (string depAssetBundleName in manifest.GetAllDependencies("【AssetBundle名】"))
              yield return loadAssetBundle(url, depAssetBundleName);
          yield return loadAssetBundle(url, "【AssetBundle名】");
      
          // ロードしたAssetBundleファイルからインスタンス生成
          AssetBundle prefabAssetBundle = loadAssetBundleList["【AssetBundle名】"];
          GameObject prefab_kani_red = prefabAssetBundle.LoadAsset<GameObject>("【Asset名】");
      }
      
      /// <summary>
      /// AssetBundleファイルロード処理
      /// </summary>
      /// <param name="url">AssetBundle格納URL</param>
      /// <param name="assetBundleName">AssetBundle名</param>
      private IEnumerator loadAssetBundle(string url, string assetBundleName)
      {
              // ロード済の場合、処理しない
              if (loadAssetBundleList.ContainsKey(assetBundleName))
                  yield break;
      
              ・・・ロード処理・・・
      		
              // ロード済AssetBundleリストに追加
              loadAssetBundleList[assetBundleName] = DownloadHandlerAssetBundle.GetContent(req);
          }
      }
      
      マイケル
      マイケル
      一点気をつけないといけないのは、同じAssetを何度もロードしないことです!
      上記処理では、loadAssetBundleList変数にロード済のAssetを保持するようにしています!
      エレキベア
      エレキベア
      複数のAssetBundleファイルがある場合は、
      ・依存性のあるAssetを事前にロードする。
      ・一度ロードしたAssetは保持しておく。

      ことが大事クマね
      マイケル
      マイケル
      そのとおり!
      それじゃこの処理を使って実装してみよう!
      今回は下記のようにカニ3種類をchar_prefab、それぞれのテクスチャをchar_textureに設定してAssetBundleファイルを作成してみます!

      ・AssetBundke名の設定

      AssetBundle名 Asset名
      char_prefab Kani_red
      char_prefab Kani_blue
      char_prefab Kani_yellow
      char_texture kani_red_col
      char_texture kani_blue_col
      char_texture kani_yellow_col
      マイケル
      マイケル
      さっき作ったフォルダと分けるため、
      今回はAssetBundle02フォルダに作成しました!
      マイケル
      マイケル
      作成されたmanifestファイルの中身を見てみると、
      char_prefabが、char_textureに依存していることが分かります!

      ↑char_prefabはchar_textureに依存している
      エレキベア
      エレキベア
      char_textureから先にロードしないといけないわけクマね
      マイケル
      マイケル
      その通り!
      新たにSceneを作成して、下記スクリプトをアタッチしてみよう!
      using System.Collections;
      using System.Collections.Generic;
      using System.IO;
      using System.Text;
      using UnityEngine;
      using UnityEngine.Networking;
      
      /// <summary>
      /// Test02Scene管理クラス
      /// </summary>
      public class Test02SceneManager : MonoBehaviour
      {
          // Manifestファイル
          AssetBundleManifest manifest;
          // ロード済AssetBundleリスト
          Dictionary<string, AssetBundle> loadAssetBundleList = new Dictionary<string, AssetBundle>(); 
      
          /// <summary>
          /// 開始処理
          /// </summary>
          void Start()
          {
              // AssetBundleロード処理
              StartCoroutine("LoadAssetBundle");
          }
      
          /// <summary>
          /// AssetBundleロード処理
          /// (Webサーバから複数ファイル取得)
          /// </summary>
          IEnumerator LoadAssetBundle()
          {
              // AssetBudnle格納URL
              string url = "http://localhost:8080/AssetBundle02/";
      
              // Manifestファイルをロード
              yield return loadAssetBundle(url, "AssetBundle02");
              manifest = loadAssetBundleList["AssetBundle02"].LoadAsset<AssetBundleManifest>("Assetbundlemanifest");
      
              // AssetBundleファイルのロード
              // (Manifestファイルから依存関係のファイルもロードする)
              foreach (string depAssetBundleName in manifest.GetAllDependencies("char_prefab"))
                  yield return loadAssetBundle(url, depAssetBundleName);
              yield return loadAssetBundle(url, "char_prefab");
      
              // ロードしたAssetBundleファイルからインスタンス生成
              AssetBundle prefabAssetBundle = loadAssetBundleList["char_prefab"];
              GameObject prefab_kani_red = prefabAssetBundle.LoadAsset<GameObject>("Kani_red");
              Instantiate(prefab_kani_red);
              GameObject prefab_kani_blue = prefabAssetBundle.LoadAsset<GameObject>("Kani_blue");
              Instantiate(prefab_kani_blue);
              GameObject prefab_kani_yellow = prefabAssetBundle.LoadAsset<GameObject>("Kani_yellow");
              Instantiate(prefab_kani_yellow);
              Debug.Log("カニ軍団をロード!!");
      
              // マウスクリックでアンロード
              yield return new WaitUntil(() => Input.GetMouseButton(0));
              prefabAssetBundle.Unload(true);
              Debug.Log("カニ軍団をアンロード!!");
          }
      
          /// <summary>
          /// AssetBundleファイルロード処理
          /// </summary>
          /// <param name="url">AssetBundle格納URL</param>
          /// <param name="assetBundleName">AssetBundle名</param>
          private IEnumerator loadAssetBundle(string url, string assetBundleName)
          {
              // ロード済の場合、処理しない
              if (loadAssetBundleList.ContainsKey(assetBundleName))
                  yield break;
              
              // AssetBundleのロード処理
              string loadUrl = Path.Combine(url, assetBundleName);
              using (UnityWebRequest req = UnityWebRequestAssetBundle.GetAssetBundle(loadUrl))
              {
                  // Webサーバーからのダウンロード待機
                  yield return req.SendWebRequest();
                  Debug.Log("http response:" + req.responseCode);
                  if (req.result == UnityWebRequest.Result.ConnectionError 
                      || req.result == UnityWebRequest.Result.ProtocolError)
                  {
                      Debug.LogError("エラー:" + req.error);
                      yield break;
                  }
                  Debug.Log("サーバからAssetBundleを取得!! -> " + assetBundleName);
      
                  // ロード済AssetBundleリストに追加
                  loadAssetBundleList[assetBundleName] = DownloadHandlerAssetBundle.GetContent(req);
              }
          }
      }
      
      マイケル
      マイケル
      これで無事にカニ達を召喚することができたね!
      エレキベア
      エレキベア
      (増えたクマ・・・。)

      差分がある場合のみロードする

      マイケル
      マイケル
      次は差分が発生した時だけロードする方法です!
      これは大きく、ロード時にバージョンを指定する方法と、ハッシュ値を指定する方法の2つがあります。
      バージョンを指定する
      マイケル
      マイケル
      バージョンを指定する方法については、下記のようにロード時に引数でバージョンを渡します!
      private string url = "【AssetBundle格納URL】";
      private uint version = 1;
      req = UnityWebRequestAssetBundle.GetAssetBundle(url, version, 0);
      ↑バージョン指定によるロード処理
      マイケル
      マイケル
      バージョンを指定することでキャッシュされて、違うバージョンを渡した時のみ再ロードするようになります!
      エレキベア
      エレキベア
      これだけでキャッシュしてくれるのは便利クマね〜〜〜
      マイケル
      マイケル
      ちなみに第3引数は、CRCチェックをする場合に指定します!
      今回は使わないので、チェックを行わないという意味の0を指定しています。
      ハッシュ値を指定する
      マイケル
      マイケル
      バージョンによる管理ができれば便利だけど、全てのAssetのバージョンを管理するのは大規模なシステムだと難しい!
      そこでもう一つ、ハッシュ値を指定する方法があります!
      マイケル
      マイケル
      ハッシュ値はManifestファイルに記載されていて、下記のように取得して引数に指定してあげると、バージョン指定と同じようにキャッシュされます!
      private string url = "【AssetBundle格納URL】";
      private Hash128 hash = manifest.GetAssetBundleHash(【AssetBundle名】);
      req = UnityWebRequestAssetBundle.GetAssetBundle(url, hash, 0);
      ↑ハッシュ値指定によるロード処理
      マイケル
      マイケル
      バージョン指定やハッシュ値指定のロード処理は、
      下記のように組み込んで使いましょう!
          /// <summary>
          /// AssetBundleロード処理
          /// (AssetBundleの変更をhash値から検知する)
          /// </summary>
          IEnumerator LoadAssetBundle()
          {
      
      ・・・略・・・
      
              // キャッシュシステムの準備を待つ
              yield return new WaitUntil(() => Caching.ready);
      
              // Manifestファイルをロード
              // (ハッシュ未使用、常にロードする)
              yield return loadAssetBundle(url, "【AssetBundle格納パス】", false);
              manifest = loadAssetBundleList["【AssetBundle格納パス】"].LoadAsset<AssetBundleManifest>("Assetbundlemanifest");
              
      ・・・略・・・
      
              // AssetBundleファイルのロード
              // (ハッシュ使用、Manifestファイルから依存関係のファイルもロードする)
              foreach (string depAssetBundleName in manifest.GetAllDependencies("【AssetBundle名】"))
                  yield return loadAssetBundle(url, depAssetBundleName, true);
              yield return loadAssetBundle(url, "【AssetBundle名】", true);
      
      ・・・略・・・
      
          }
      
          /// <summary>
          /// AssetBundleファイルロード処理
          /// </summary>
          /// <param name="url">AssetBundle格納URL</param>
          /// <param name="assetBundleName">AssetBundleファイル名</param>
          /// <param name="useHash">ロードにハッシュを使用するか</param>
          private IEnumerator loadAssetBundle(string url, string assetBundleName, bool useHash)
          {
              // ロード済の場合、処理しない
              if (loadAssetBundleList.ContainsKey(assetBundleName))
                  yield break;
              
              // hashの有無によりロード方法を変更
              string loadUrl = Path.Combine(url, assetBundleName);
              UnityWebRequest req;
              if (useHash)
              {
                  // hashを使用する場合、変更分のみロードする
                  Hash128 hash = manifest.GetAssetBundleHash(assetBundleName);
                  req = UnityWebRequestAssetBundle.GetAssetBundle(loadUrl, hash, 0);
              }
              else
              {
                  // hashを使用しない場合、常にロードする
                  req = UnityWebRequestAssetBundle.GetAssetBundle(loadUrl);
              }
      
              // AssetBundleのロード処理
              using (req)
              {
                  // Webサーバーからのダウンロード待機
                  yield return req.SendWebRequest();
                  Debug.Log("http response:" + req.responseCode);
                  if (req.result == UnityWebRequest.Result.ConnectionError 
                      || req.result == UnityWebRequest.Result.ProtocolError)
                  {
                      Debug.LogError("エラー:" + req.error);
                      yield break;
                  }
                  Debug.Log("サーバからAssetBundleを取得!! -> " + assetBundleName);
                  // ロード済AssetBundleリストに追加
                  loadAssetBundleList[assetBundleName] = DownloadHandlerAssetBundle.GetContent(req);
              }
          }
      マイケル
      マイケル
      キャッシュされているかどうかは、req.responseCodeで確認することができます!
      2回目以降の実行で、下記のようにレスポンスが0で返ってきていれば上手くキャッシュ出来ています!

      ↑キャッシュ後のロード処理
      マイケル
      マイケル
      キャッシュされた後、位置を変えるなど変更を加えた後に再ビルドすると、レスポンスが200で返ってきて再ロードされていることも確認できます!

      ↑再ロード処理
      エレキベア
      エレキベア
      うまく効いてるクマね〜〜

      おわりに

      マイケル
      マイケル
      というわけで今回はAssetBundleを触ってみました!
      どうだったかな?
      エレキベア
      エレキベア
      なかなか慣れるまでが大変そうクマね〜〜
      でもアプリと分離化できるのは便利クマ!
      マイケル
      マイケル
      大規模なゲーム開発となると、
      使うのはほぼ必須になると思うから、がんばって慣れていこう!!
      マイケル
      マイケル
      それでは今日はこの辺で!!
      アデューー!!
      エレキベア
      エレキベア
      クマ〜〜〜〜〜〜

      【Unity】AssetBundleを使ってリソースを管理する 〜完〜


      Unity
      2021-04-19

      関連記事
      【Unity】Timeline × Excelでスライドショーを効率よく制作する
      2024-10-31
      【Unity】Boidsアルゴリズムを用いて魚の群集シミュレーションを実装する
      2024-05-28
      【Unity】GoでのランキングAPI実装とVPSへのデプロイ方法についてまとめる【Go言語】
      2024-04-14
      【Unity】第二回 Wwiseを使用したサウンド制御 〜インタラクティブミュージック編〜
      2024-03-30
      【Unity】第一回 Wwiseを使用したサウンド制御 〜基本動作編〜
      2024-03-30
      【Unity】第二回 CRI ADXを使用したサウンド制御 〜インタラクティブミュージック編〜
      2024-03-28
      【Unity】第一回 CRI ADXを使用したサウンド制御 〜基本動作、周波数解析編〜
      2024-03-28
      【Unity】サウンドミドルウェアに依存しない設計を考える【CRI ADX・Wwise】
      2024-03-27