AssetBundle
AB包是什么?
AssetBundle又称AB包,是Unity提供的一种用于存储资源的资源压缩包。
Unity中的AssetBundle系统是对资源管理的一种扩展,通过将资源分布在不同的AB包中可以最大程度地减少运行时的内存压力,可以动态地加载和卸载AB包,继而有选择地加载内容。
AB包的优势有哪些?
- AB包的存储位置自定义。可以放入可读可写的路径下便于实现热更。
- 可以自定义压缩方式。对于压缩方式可以选择不压缩或者LZMA和LZ4等不同的压缩方式压缩,满足不同的网络传输需求。
- 资源可以分布在不同的AB包体中,可以最大程度减少运行时候的内存压力,做到即用即加载,针对性的加载。
- AB包支持后期进行动态更新。支持热更,可以显著减小初始安装包的大小,非必要的核心关卡可以跟随用户闯关进度来进行资源下载,提高用户的体验。
AB包与Resources的比较?
AB包 | Resource |
---|---|
资源可分布在多个包中 | 所有资源打成一个大包 |
存储位置可自定义 | 必须放在Resources目录下 |
压缩方式灵活 | 资源全部压缩成二进制 |
支持后期进行动态更新 | 打包后资源只读无法动态更改 |
AB包的特点与要求
- AB包无法直接存储C#脚本。代码的热更需要使用lua这类脚本语言,或者存储编译后的DLL文件。
- AB包不能重复进行加载。AB包已经加载进内存后必须卸载后才能重新加载。
- AB包之间是存在依赖关系的,在加载当前AB包时需要一并加载其所依赖的包。
- 打包完成后,会自动生成一个主包(主包名称随平台不同而不同),主包的manifest下会存储有版本号、校验码(CRC)、所有其它包的相关信息(名称、依赖关系)
AB包打包实操
-
下载导入Asset Bundles 资源包 【】
-
将需要打包的资源进行分组分类
- 打开AssetBundle 打包窗口进行设置 Build 出包
AB包的文件内容分为两类:
一类是资源文件(无后缀名称的)
另一类为mainfest文件 存储AB包体的信息和加载时候所需的关键信息、资源信息、版本信息、依赖关系等等
关键AB包(与目录名同名)为主包 和 AB包依赖的关键信息
加载AB包中的资源
C#
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
namespace LearnAssetBundle
{
public class LoadAsset : MonoBehaviour
{
private AssetBundle ab;
private Image _image;
private void Awake()
{
//获取AB包 打包的文件已经拷贝到streamingAssets文件下 从此位置加载
//注意!AB包不能重复加载
ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath +"/"+"model");
_image = GameObject.Find("Canvas/Image").GetComponent<Image>();
}
void Start()
{
GameObject cube = ab.LoadAsset<GameObject>("cube");
Instantiate(cube);
//使用异步加载图片资源
StartCoroutine(LoadPicRes("pic", "bk"));
//释放掉 true 包括场景中的资源
ab.Unload(false);
}
private IEnumerator LoadPicRes(string AbName, string picName)
{
AssetBundleCreateRequest picAb = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/" + AbName);
AssetBundleRequest abERes = picAb.assetBundle.LoadAssetAsync(picName, typeof(Sprite));
yield return abERes;
_image.sprite = abERes.asset as Sprite;
}
void Update()
{
//AB包资源的卸载
if (Input.GetKeyDown(KeyCode.Space))
{
//卸载所有加载的AB包
// true 包括场景中正在使用的资源 谨慎使用
// false 仅卸载ab包的资源 场景中的资源不受影响
AssetBundle.UnloadAllAssetBundles(false);
}
}
}
}