AssetBundle工作流与分配策略

AssetBundle工作流程

将资产分配给AssetBundles
要将给定资产分配给AssetBundle,请按照下列步骤操作:

  1. 从项目视图中选择要分配给捆绑包的资产
  2. 检查检查器中的对象
  3. 在检查器的底部,您应该看到一个分配AssetBundles和Variants的部分:
  4. 左侧下拉分配AssetBundle,而右侧下拉分配变量
  5. 单击左侧下拉列表,显示“无”,以显示当前已注册的AssetBundle名称
  6. 单击“新建…”以创建新的AssetBundle
  7. 输入所需的AssetBundle名称。请注意,AssetBundle名称确实支持一种文件夹结构,具体取决于您键入的内容。要添加子文件夹,请用“/”分隔文件夹名称。例如:AssetBundle名称“environment / forest”将在环境子文件夹下创建名为forest的包
  8. 一旦选择或创建了AssetBundle名称,您可以重复此过程以右手下拉以分配或创建变体名称(如果需要),构建AssetBundle不需要变体名称。

添加打包工具栏

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);
    }
}

这样就会有一个打包工具,如果不是WIN平台,自行更改BuildTarget。

那如何加载

打算从本地存储加载:

public class LoadFromFileExample extends 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);
    }
}

自己托管AssetBundles并需要将它们下载到游戏中

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);
    }

GetAssetBundle(string, int)获取AssetBundle的位置的URL以及要下载的包的版本。
在此示例中,我们仍然指向本地文件,但string url可以指向您拥有AssetBundles的任何URL。
UnityWebRequest有一个特定的句柄来处理AssetBundles
DownloadHandlerAssetBundle,它从请求中获取AssetBundle。

分配策略

三种大的分配策略:

  • 逻辑实体分组:

    根据资源所代表的项目功能部分分配,比如资源属于用户界面,角色,环境等,这样来分配。
    意思就是在根据游戏中的逻辑上的实体来分配,比如属于角色的所有东西都打在角色的包里面
    逻辑实体分组特别适用于可下载内容(DLC),比如这个DLC只是更改了一些场景景物,那么我们只需要更改我们的场景模型包,而玩家也只需要下载这个更改后的包。
    但是我的想法是另外一种:
    比如在场景修改某个物体或者添加了一些新的下载内容后,我们只需要将这些修改后的或者新的内容打入新的AB包就可以只下载新的AB包。在玩家拥有DLC时,加载新的AB包就可以了。如果没有DLC那么就只加载旧的包,这样的缺点也很明显,就是所有的东西都被杂糅到了新包里面。更好的方式是依旧按照之前的方式分类,新的角色模型打入一个新包,新的场景打入另一个新包,这样玩家既可以不用下载之前的内容,又可以很好地分类。

  • 类型分组:
    将相似的资源分配到一个包,比如音频在一个包,动画在一个包,模型在一个包等

  • 并发内容分组:
    将需要同时加载和使用的资源捆绑在一起,这种方式就是基于关卡的,比如这个关卡有一些特殊的东西,而其他关卡都没有的,那么就把这些特殊的东西打在一起。

遵循原则

  • 将频繁更新的对象拆分为AssetBundle,与很少更改的对象分开
  • 对可能同时加载的对象进行分 组。例如模型,纹理和动画。
  • 如果您注意到多个AssetBundle中的多个对象依赖于来自完全不同的AssetBundle的单个资产,请将依赖项移动到单独的AssetBundle。如果多个AssetBundle引用其他AssetBundle中的同一组资产,则可能值得将这些依赖项拉入共享AssetBundle以减少重复。
  • 如果不可能同时加载两组对象,例如标准和高清属性,请确保它们位于自己的AssetBundle中。
  • 如果同时经常加载50%的捆绑包,请考虑拆分AssetBundle。
  • 考虑组合小型(少于5到10个资产)但其内容经常同时加载的AssetBundle。
  • 如果一组对象只是同一对象的不同版本,请考虑AssetBundle Variants。

本文部分内容引用字Unity官方文档

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章