文章目录
- 一、AB 包介绍
- 二、AB 包资源打包
- (一)导入 AB 包
- (二)将资源关联 AB 包
- (三)打包参数选项
- (四)打包结果
- (五)AB 包信息
- 三、加载 AB 包资源
- (一)同步加载
- (二)异步加载
- (三)卸载 AB 包
- (四)AB 包依赖
一、AB 包介绍
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。
下载完成后解压文件夹到项目中,若导入后报错,只需删除导入内容中的事例文件夹即可。
(二)将资源关联 AB 包
点击需要关联的资源,这里选图片 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:压缩方式
- NoCompression:不压缩,解压快,包较大 不推荐
- LZMA:压缩最小,解压慢
- 缺点:用一个资源 要解压所有
- LZ4:压缩,相对 LZMA 大一点点
- 建议使用,用什么解压什么,内存占用低
-
其他(非重要参数)
-
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 包的关键依赖关系。
(五)AB 包信息
点击 Inspect 页签,可以看到 AB 包的详细信息。
三、加载 AB 包资源
使用 AB 包加载资源主要分为 2 步:
- 加载 AB 包
- 加载 AB 包中的资源
注意: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<GameObject>("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 包
-
卸载所有 AB 包:
AssetBundle.UnloadAllAssetBundles(bool unloadAllObjects);
-
卸载单个 AB 包 ab:
ab.UnloadAllAssetBundles(bool unloadAllObjects);
- unloadAllObjects:决定是否卸载场景中 AB 包所创建的资源
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<GameObject>("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);
}
}
}
(四)AB 包依赖
当 A 包中的某个资源 a 使用了另一个资源 b,则打包时会将 b 默认打包到 A 包中。
如果将资源 b 手动打包进 B 包中,则 A 包中有资源依赖于 B 包。
此时,如果要使用资源 a,则需要同时加载 A 包和 B 包。
具体操作如下:
-
加载主包
AssetBundle abMain = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/StandaloneWindows");
-
加载主包中的固定文件
AssetBundleManifest abManifest = abMain.LoadAsset<AssetBundleManifest>(nameof(AssetBundleManifest);
-
从固定文件中获取 monsters 包的依赖信息
string[] strs = abManifest.GetAllDependencies("monsters");
-
加载依赖包
for (int i = 0; i < strs.Length; i++) { AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + strs[i]); }