AB 包理论基础

学习目标

  1. AB 包是什么
  2. AB 包有什么作用
  3. 生成 AB 包资源文件
  4. 使用 AB 包资源文件
  5. AB 包资源加载管理器

AB 包是什么

  • 特定于平台(安卓、IOS、PC)的资产压缩包,有点类似压缩文件
  • 资产包括:模型、贴图、预设体、音效、材质球等等, 可以将 C#代码打包,所以需要 lua 来做热更新

AB 包有什么作用

  • 相对 Resources 下的资源,AB 包更好管理资源 Resources:打包时定死,只读,无法修改;AB 包:存储位置可自定,压缩方式自定义,后期可以动态更新(网络,本地更新)。还可以减小包体大小,压缩资源,减少初始包大小

AB 包资源加载和 Resources 资源加载区别

  1. API 不同
  2. Resources 加载的资源,一定得放在 Resources 文件夹下
    AB 包理论上来说放在任何地方都可以,但一般都放在 Application.streamingAssetsPath 或 Application.persistentDataPath
  3. AB 包中是资源集合,Resources 下都是单个资源

AB 包资源打包

AssetBundle - Unity 手册

在 Unity 当中导入 Asset Bundle Browser

绑定资源到 AB 包

AssetBundle 工作流程 - Unity 手册

AB 包资源加载

使用 AssetBundle 类加载资源

同步加载

1
2
AssetBundle ab = AssetBundle.LoadFromFile(path);
ab.LoadAsset<GameObject>("Cube")
1
2
3
4
5
//第一步,加载AB包
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + "model");
//第二步,加载AB包中的资源
GameObject cube = ab.LoadAsset<GameObject>("Cube");
Instantiate(cube);

注意:不能重复加载同一个 AB 包,否则会报错

异步加载

1
2
3
4
5
6
7
8
9
10
11
private IEnumerator LoadAsset(string path, string assetName)
{
//第一步:加载AB包
AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(path);
yield return abcr;
//第二步:加载资源
AssetBundleRequest abr = abcr.assetBundle.LoadAssetAsync<GameObject>(assetName);
yield return abr;
//使用资源
Instantiate(abr.asset);
}

卸载 AB 包

卸载所有 AB 包

1
AssetBundle.UnloadAllAssetBundles(false);

传入的 bool

  • true:卸载已经使用的资源(也就是说场景当中使用了 AB 包中资源的对象将丢失资源)
  • false:不卸载

卸载单个

1
2
3
4
5
6
7
8
//第一步,加载AB包
AssetBundle ab = AssetBundle.LoadFromFile(path);
//第二步,加载AB包中的资源
GameObject cube = ab.LoadAsset<GameObject>("Cube");
Instantiate(cube);

//卸载本身
ab.Unload(false);

AB 包依赖

关于 AB 包的依赖 — 一个资源身上用到了别的 AB 包中的资源。

这个时候如果只加载自己的 AB 包,通过它创建对象会出现资源丢失的情况。

这种时候需要把依赖包一起加载了才能正常。

我们可以通过加载主包,然后获取主包当中的Manifest文件,再通过 Manifest 文件获取某个包的所有依赖

1
2
3
4
5
6
7
8
9
10
11
12
//利用主包,获取依赖信息
//加载主包
AssetBundle abMain = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + "PC");
//加载主包中的固定文件
AssetBundleManifest abManifest = abMain.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//从固定文件中得到依赖信息
string[] strs = abManifest.GetAllDependencies("model");
//获取依赖名后,一个个加载ab包
for (int i = 0; i < strs.Length; ++i)
{
AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + strs[i]);
}

注意:AB 包依赖,只能记录包与包之前的依赖,而不能记录包内资源自己的依赖。

比如:A 包当中的 1 资源依赖了 B、C 包,2 资源依赖了 D、E 包,那么 A 包的依赖就是 B、C、D、E,而不能记录 1 资源依赖了谁,2 资源依赖了谁。