AssetBundle

AssetBundle

AssetBundle 是一个存档文件,包含可在运行时由 Unity 加载的特定于平台的非代码资源(比如模型、纹理、预制件、音频剪辑甚至整个场景)。

AssetBundle 工作流程

为 AssetBundle 分配资源

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

  • 从 Project 视图中选择要为捆绑包分配的资源。
  • 在 Inspector 底部,有一个用于分配 AssetBundle 和变体的部分。可使用左侧下拉选单分配 AssetBundle,而使用右侧下拉选单分配变量。
  • 单击左侧下拉选单的 None 以显示当前注册的 AssetBundle 名称。 单击 New 以创建新的 AssetBundle 。
  • 输入所需的 AssetBundle 名称。注意:AssetBundle 名称支持某种类型的文件夹结构,具体取决于您输入的内容。要添加子文件夹,请用 / 分隔文件夹名称。
  • 一旦选择或创建了 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);
    }
}

加载 AssetBundle 和资源

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

public class LoadFromFileExample : MonoBehaviour {
    function 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);
    }
}

如果是您自己托管 AssetBundle 并需要将它们下载到应用程序中,请使用 UnityWebRequest API。下面是一个示例:

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

并发内容分组

  • 将频繁更新的对象与很少更改的对象拆分到不同的 AssetBundle 中
  • 将可能同时加载的对象分到一组。例如模型及其纹理和动画
  • 如果发现多个 AssetBundle 中的多个对象依赖于另一个完全不同的 AssetBundle 中的单个资源,请将依赖项移动到单独的 AssetBundle。如果多个 AssetBundle 引用其他 AssetBundle 中的同一组资源,一种有价值的做法可能是将这些依赖+ 项拉入一个共享 AssetBundle 来减少重复。
  • 如果不可能同时加载两组对象(例如标清资源和高清资源),请确保它们位于各自的 AssetBundle 中。
  • 如果一个 AssetBundle 中只有不到 50% 的资源经常同时加载,请考虑拆分该捆绑包
  • 考虑将多个小型的(少于 5 到 10 个资源)但经常同时加载内容的 AssetBundle 组合在一起
  • 如果一组对象只是同一对象的不同版本,请考虑使用 AssetBundle 变体
posted @ 2021-06-26 17:09  镜子-眼泪  阅读(257)  评论(0)    收藏  举报