AB 包是特定于平台的资源压缩包,类似于压缩文件。其中资源可包括:模型、贴图、预设体、音效、材质球等等。
相较于 Resources 文件夹下的资源文件,AB 包能够更好管理资源:
Resources 文件夹:打包时资源固定,只读,无法修改。
AB 包:存储位置可自定义,压缩方式可自定义,后期可动态更新。
用途:
减小包体大小
热更新
第一步:
获取资源服务器地址
第二步:
通过资源对比文件
检测和更新AB包
客户端
自带很少的默认资源
资源对比文件
服务器端
资源服务器
资源对比文件
最新的各种AB包
Unity2019 版本:
在 Window ->
Package Manager 中搜索 “Asset Bundle Browser” 进行安装。
安装完成后,在 Project 窗口下可看见 AB 包。
2019 以上版本:
对于高版本 Unity,不能通过包管理器进行下载。原因:高版本 Unity 用 Addressables 功能封装了 AB 包功能。
如果仍要使用 AB 包,在 GitHub 上搜索 AssetBundles 下载对应压缩包,对应链接:GitHub - Unity-Technologies/AssetBundles-Browser: Editor tool for viewing and debugging asset bundle contents before and after builds。
下载完成后解压文件夹到项目中,若导入后报错,只需删除导入内容中的事例文件夹即可。
点击需要关联的资源,这里选图片 fat_boss_green01.png
。
在 Inspector 窗口下方的 AssetBundle 窗口内点击 new 新建 AB 包 monsters,即可将资源装进 monster 包。
点击 Window ->
AssetBundle Browser,在 Configure 页签下可以查看新建的 AB 包以及对应关联的资源。
点击 Build 页签,可以看到有如下打包配置参数:
Build Target:目标平台
Output Path:目标输出路径
Clear Folders:是否清空文件夹 重新打包
Copy To StreamingAssets:是否拷贝到 StreamingAssets 文件夹下
Compression:压缩方式
其他(非重要参数)
Exclude Type Information:在资源包中不包含资源的类型信息
Force Rebuild:重新打包时需要重新构建包
和 Clear Folders 不同,它不会删除不再存在的包
Ignore Type Tree Changes:增量构建检查时,忽略类型数的更改
Append Hash:将文件哈希值附加到资源包名上
Strict Mode:严格模式,如果打包时报错了,则打包直接失败无法成功
Dry Run Build:运行时构建
maps / monsters:
maps 包和 monsters 包,为二进制文件,记录了资源数据。
maps.manifest / monsters.manifest:
maps 包和 monsters 包的配置文件,为文本文件,记录了对应资源文件的配置信息。
资源信息(Assets)
依赖关系(Dependencies)
版本信息(ManifestFileVersion)
等等
StandaloneWindows / StandaloneWindows.manifest:
所有 AB 包的主包(包名和文件目录名称一样),记录了所有 AB 包的关键依赖关系。
点击 Inspect 页签,可以看到 AB 包的详细信息。
使用 AB 包加载资源主要分为 2 步:
注意:AB 包不能重复加载,否则会报错。
以下示例默认 AB 包存储在路径 Application.streamingAssetsPath
下。
public class ABTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
// 第一步 加载 AB 包
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/model");
// 第二步 加载 AB 包中的资源
// 只用名字加载 会出现同名不同类型资源 分不清
// 建议使用 泛型加载
GameObject cube = ab.LoadAsset("Cube");
// GameObject cube = ab.LoadAsset("Cube", typeof(GameObject)) as GameObject;
Instantiate(cube);
}
}
public class ABTest : MonoBehaviour
{
public Image image;
// Start is called before the first frame update
void Start()
{
// 异步加载——协程
StartCoroutine(LoadABRes("monsters", "fly_yellow02.png"));
}
IEnumerator LoadABRes(string ABName, string resName) {
// 第一步 加载 AB 包
AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/" + ABName);
yield return abcr;
// 第二步 加载 AB 包中的资源
AssetBundleRequest abq = abcr.assetBundle.LoadAssetAsync(resName, typeof(Sprite));
yield return abq;
image.sprite = abq.asset as Sprite;
}
}
卸载所有 AB 包:
AssetBundle.UnloadAllAssetBundles(bool unloadAllObjects);
卸载单个 AB 包 ab:
ab.UnloadAllAssetBundles(bool unloadAllObjects);
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ABTest : MonoBehaviour
{
public Image image;
// Start is called before the first frame update
void Start()
{
// 第一步 加载 AB 包
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/model");
// 第二步 加载 AB 包中的资源
// 只用名字加载 会出现同名不同类型资源 分不清
// 建议使用 泛型加载
GameObject cube = ab.LoadAsset("Cube");
Instantiate(cube);
// 卸载单个 AB 包
ab.Unload(false);
// 加载一个球
GameObject sphere = ab.LoadAsset("Sphere", typeof(GameObject)) as GameObject;
Instantiate(sphere);
// 异步加载——协程
StartCoroutine(LoadABRes("monsters", "fly_yellow02.png"));
}
IEnumerator LoadABRes(string ABName, string resName) {
// 第一步 加载 AB 包
AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/" + ABName);
yield return abcr;
// 第二步 加载 AB 包中的资源
AssetBundleRequest abq = abcr.assetBundle.LoadAssetAsync(resName, typeof(Sprite));
yield return abq;
image.sprite = abq.asset as Sprite;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space)) {
// 卸载所有加载的 AB 包 参数为 true 会把通过 AB 包加载的资源也卸载
AssetBundle.UnloadAllAssetBundles(false);
}
}
}
当 A 包中的某个资源 a 使用了另一个资源 b,则打包时会将 b 默认打包到 A 包中。
如果将资源 b 手动打包进 B 包中,则 A 包中有资源依赖于 B 包。
此时,如果要使用资源 a,则需要同时加载 A 包和 B 包。
具体操作如下:
加载主包
AssetBundle abMain = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/StandaloneWindows");
加载主包中的固定文件
AssetBundleManifest abManifest = abMain.LoadAsset(nameof(AssetBundleManifest);
从固定文件中获取 monsters 包的依赖信息
string[] strs = abManifest.GetAllDependencies("monsters");
加载依赖包
for (int i = 0; i < strs.Length; i++) {
AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + strs[i]);
}