Unity 热更--AssetBundle学习笔记 0.7

AssetBundle

AB包是什么?

AssetBundle又称AB包,是Unity提供的一种用于存储资源的资源压缩包

Unity中的AssetBundle系统是对资源管理的一种扩展,通过将资源分布在不同的AB包中可以最大程度地减少运行时的内存压力,可以动态地加载和卸载AB包,继而有选择地加载内容。

AB包的优势有哪些?

  1. AB包的存储位置自定义。可以放入可读可写的路径下便于实现热更。
  2. 可以自定义压缩方式。对于压缩方式可以选择不压缩或者LZMA和LZ4等不同的压缩方式压缩,满足不同的网络传输需求。
  3. 资源可以分布在不同的AB包体中,可以最大程度减少运行时候的内存压力,做到即用即加载,针对性的加载。
  4. AB包支持后期进行动态更新。支持热更,可以显著减小初始安装包的大小,非必要的核心关卡可以跟随用户闯关进度来进行资源下载,提高用户的体验。

AB包与Resources的比较?

AB包 Resource
资源可分布在多个包中 所有资源打成一个大包
存储位置可自定义 必须放在Resources目录下
压缩方式灵活 资源全部压缩成二进制
支持后期进行动态更新 打包后资源只读无法动态更改

AB包的特点与要求

  1. AB包无法直接存储C#脚本。代码的热更需要使用lua这类脚本语言,或者存储编译后的DLL文件。
  2. AB包不能重复进行加载。AB包已经加载进内存后必须卸载后才能重新加载。
  3. AB包之间是存在依赖关系的,在加载当前AB包时需要一并加载其所依赖的包。
  4. 打包完成后,会自动生成一个主包(主包名称随平台不同而不同),主包的manifest下会存储有版本号、校验码(CRC)、所有其它包的相关信息(名称、依赖关系)

AB包打包实操

  1. 下载导入Asset Bundles 资源包 【】

  2. 将需要打包的资源进行分组分类

  1. 打开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);
            }
        }
    }
}