Unity でのアセット バンドルの使用法

Unity には多くの便利な機能があり、その 1 つはアセット バンドルのサポートです。

アセットバンドルとは何ですか?

アセット バンドルは、3D モデル、テクスチャ、オーディオ クリップ などの単純なアセットから、シーンや プレハブ などのより複雑なアセットまで、ゲーム アセットを含むファイルです。

ただし、スクリプトはアセット バンドルに含めることはできず、その参照のみを含めることができます。そのため、スクリプトの名前を変更したり移動したりする場合は注意してください。接続が切断され、再度機能させるにはアセット バンドルを再構築する必要があります。

アセット バンドルをいつ使用するか?

ゲームに多くのアセットがあり、それらをビルドに含めると初期ダウンロード時間に影響する場合は、アセット バンドルを使用します。

アセットバンドルのエクスポート

アセット バンドルのエクスポートは 2 つの手順で行われます。アセット バンドル名の割り当てと、エディタ script を使用したアセット バンドルの構築です。

アセットバンドル名の割り当て

アセット バンドル名を割り当てるには、プロジェクト ビューでアセットを選択し (プレハブ、テクスチャ、またはシーンでも構いません)、次にインスペクター ビューの最下部にあるドロップダウン メニューをクリックしてから、'New...' (または既存のアセット バンドル名をクリックします)。

複数のアセットに同じバンドル名を割り当てると、それらは同じアセット バンドルにまとめられます。シーンを残りのアセットとは別にパックすることをお勧めします。

また、すべてのアセットにアセット バンドル名を割り当てる必要はありません。通常、メインのプレハブまたはアセットにバンドル名を割り当てるだけで済み、残りの依存関係は自動的に含まれます。

アセット バンドルの構築

アセット バンドルを構築するには、以下の手順に従います。

  • Editor という名前の新しいフォルダーを作成します (エディターがない場合)。
  • Editor フォルダー内に という新しいスクリプトを作成し、BuildAssetBundles という名前を付けて、その中に以下のコードを貼り付けます。

BuildAssetBundles.cs

using UnityEngine;
using UnityEditor;

public class BuildAssetBundles
{
    [MenuItem("Build/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        string outputFolder = "Assets/__Bundles";

        //Check if __Bundles folder exist
        if (!AssetDatabase.IsValidFolder(outputFolder))
        {
            Debug.Log("Folder '__Bundles' does not exist, creating new folder");

            AssetDatabase.CreateFolder("Assets", "__Bundles");
        }

        BuildPipeline.BuildAssetBundles(outputFolder, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);
    }
}

保存すると、メニュー ボタン (Build -> Build AssetBundles) が追加されることがわかります。これをクリックすると、アセット バンドルが構築され、"__Bundles" フォルダーに配置されます。

アセット バンドルのロード

アセット バンドルをロードするには、まず UnityWebRequest を使用してダウンロードし、次に特別な関数を使用して解凍する必要があります。一般に、アセット バンドルには、アセットを含むバンドルとシーンを含むバンドルの 2 種類があります。

アセット バンドルからのアセットのロード

以下のコードは、"fpsplayer" という名前のアセット バンドルをダウンロードし、"FPSPlayer" という名前のプレハブを抽出してシーン内でインスタンス化します。

        int assetBundleVersion = 1; // Changing this number will force Asset Bundle reload
        string assetBundlePath = "file://" + Application.dataPath + "/__Bundles/" + "fpsplayer"; // Path to Asset Bundle file
        using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(assetBundlePath, (uint)assetBundleVersion, 0))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.LogError("AssetBundle Error: " + www.error);
                yield return null;
            }
            else
            {
                // Get downloaded Asset Bundle
                AssetBundle assetBundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(www);
                // Extract Prefab named "FPSPlayer" from the Asset Bundle
                GameObject playerPrefab = assetBundle.LoadAsset("FPSPlayer") as GameObject;
                // Instantiate Player Prefab
                Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
                // Unload Asset Bundle from memory (but do not destroy the existing instance(s))
                assetBundle.Unload(false);
            }
        }

アセット バンドルからのシーンのロード

アセット バンドルからシーンをロードする方法は少し異なります。

以下のコードは、シーンを含むアセット バンドルをダウンロードし、ロードできるようにします。

        int assetBundleVersion = 1; // Changing this number will force Asset Bundle reload
        string assetBundlePath = "file://" + Application.dataPath + "/__Bundles/" + "testscene"; // Path to Asset Bundle file
        using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(assetBundlePath, (uint)assetBundleVersion, 0))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.LogError("AssetBundle Error: " + www.error);
                yield return null;
            }
            else
            {
                // Get downloaded Asset Bundle (This will make the Scene available for load)
                AssetBundle assetBundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(www);
                // Load the Scene extracted from the Asset Bundle
                UnityEngine.SceneManagement.SceneManager.LoadScene("TestScene");
            }
        }
おすすめの記事
Unity のオーディオに関するガイド
Unity で地形に木をペイントする方法
アニメーションを Unity にインポートする方法
Unity での環境に適した Skybox の選択
Unity ゲームを著作権侵害から守る戦略
Unity で FNAF にインスピレーションを得たゲームを作成する方法
Unity ゲーム開発におけるストーリーテリングの重要性