Version: 2022.3
AssetBundle
为 AssetBundle 准备资源

AssetBundle 工作流程

要开始使用 AssetBundle,请按照以下步骤操作。有关每个工作流程的更多详细信息,请参阅本文档这一部分的其他页面。

Note: This section describes the creation of AssetBundles using the built-in BuildPipeline.BuildAssetBundles() API. A recommended, and more user friendly, alternative is to use the Addressables package.

为 AssetBundle 分配资源

要为 AssetBundle 分配指定资源,请按照下列步骤操作:

  1. 从 Project 视图中选择要为捆绑包分配的资源。
  2. 在 Inspector 中检查对象。
  3. 在 Inspector 底部,有一个用于分配 AssetBundle 和变体的部分。可使用左侧下拉选单分配 AssetBundle,而使用右侧下拉选单分配变量。
  4. 单击左侧下拉选单的 None 以显示当前注册的 AssetBundle 名称。
  5. 单击 New 以创建新的 AssetBundle
  6. 输入所需的 AssetBundle 名称。注意:AssetBundle 名称支持某种类型的文件夹结构,具体取决于您输入的内容。要添加子文件夹,请用 / 分隔文件夹名称。例如,使用 AssetBundle 名称 environment/forestenvironment 子文件夹下创建名为 forest 的捆绑包
  7. 一旦选择或创建了 AssetBundle 名称,便可以重复此过程在右侧下拉选单中分配或创建变体名称(如果需要)。构建 AssetBundle 不需要变体名称

Note: In the Inspector you can assign an AssetBundle to a folder in your Project. By default, all Assets in that folder are assigned to the same AssetBundle as the folder. The AssetBundle assignments for individual Assets takes precedence, however.

要阅读有关 AssetBundle 分配和相关策略的更多信息,请参阅关于为 AssetBundle 准备资源的文档。

构建 AssetBundle

在 Assets 文件夹中创建一个名为 Editor 的文件夹,并将包含以下内容的脚本放在该文件夹中:

using UnityEditor;
using System.IO;

public class CreateAssetBundles
{
    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        string assetBundleDirectory = "Assets/AssetBundles";
        if(!Directory.Exists(assetBundleDirectory))
        {
            Directory.CreateDirectory(assetBundleDirectory);
        }
        BuildPipeline.BuildAssetBundles(assetBundleDirectory, 
                                        BuildAssetBundleOptions.None, 
                                        BuildTarget.StandaloneWindows);
    }
}

此脚本将在 Assets 菜单底部创建一个名为 Build AssetBundles 的菜单项,该菜单项将执行与该标签关联的函数中的代码。单击 Build AssetBundles 时,将随构建对话框一起显示一个进度条。此过程将会获取带有 AssetBundle 名称标签的所有资源,并将它们放在 assetBundleDirectory 定义的路径中的文件夹中。

Note: You can also define the content of AssetBundles programmatically instead of using the Inspector-based method described above. This is available by using a signature of BuildPipeline.BuildAssetBundles that accepts an array of AssetBundleBuild structures. In that case the list of desired Assets for each bundle are passed in, and any assignment to AssetBundles made in the Inspector is ignored.

如需了解与此相关的更多详细信息,请参阅关于构建 AssetBundle 的文档。

加载 AssetBundle 和资源

如果您想从本地存储中加载,请使用 AssetBundles.LoadFromFile API,如下所示:

public class LoadFromFileExample : MonoBehaviour {
    void Start() {
        var myLoadedAssetBundle 
            = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "myassetBundle"));
        if (myLoadedAssetBundle == null) {
            Debug.Log("Failed to load AssetBundle!");
            return;
        }
        var prefab = myLoadedAssetBundle.LoadAsset<GameObject>("MyObject");
        Instantiate(prefab);
    }
}

LoadFromFile 获取捆绑包文件的路径。

If your AssetBundles are hosted online, or you are running on a platform that does not support direct file system access, then use the UnityWebRequestAssetBundle API. Here’s an example:

IEnumerator InstantiateObject()
{
    string url = "file:///" + Application.dataPath + "/AssetBundles/" + assetBundleName;        
    var request 
        = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(url, 0);
    yield return request.Send();
    AssetBundle bundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(request);
    GameObject cube = bundle.LoadAsset<GameObject>("Cube");
    GameObject sprite = bundle.LoadAsset<GameObject>("Sprite");
    Instantiate(cube);
    Instantiate(sprite);
}

GetAssetBundle(string, int) takes the URL of the location of the AssetBundle and the version of the bundle you want to download. This example points to a local file, but string url could point to any URL you have your AssetBundles hosted at.

UnityWebRequestAssetBundle 类有一个特定的句柄来处理 AssetBundle: DownloadHandlerAssetBundle,它可根据请求获取 AssetBundle。

无论使用哪种方法,现在都可以访问 AssetBundle 对象了。对该对象需要使用 LoadAsset<T>(string),此函数将获取您尝试加载的资源的类型 T 以及对象的名称(作为捆绑包内部的字符串)。这将返回从 AssetBundle 加载的任何对象。可以像使用 Unity 中的任何对象一样使用这些返回的对象。例如,如果要在场景中创建游戏对象,只需调用 Instantiate(gameObjectFromAssetBundle)

有关用于加载 AssetBundle 的 API 的更多信息,请参阅关于本机使用 AssetBundle 的文档。

AssetBundle
为 AssetBundle 准备资源