Unity AssetBundle 解析 (一)AB包介绍与构建

介绍

AssetBundle是Unity提供的一种资源存储压缩包,包含了一些Unity的资源,如图片,模型,纹理,音视频等等,也可以包含用户自定义的二进制文件。提供了一种程序运行时动态加载资源包的方法,如游戏中不同版本的资源更新即通过更新资源AB包即可。

Unity官方文档描述AssetBundle为一个容器,就像文件夹一样,包含其他文件。这些其他文件有两种类型,一种是序列化文件,包含资产分解成单独的对象并写到该单个文件中。(o((⊙﹏⊙))o,在说什么);另一种是资源文件,是为某些资产(纹理和音频)单独存储的二进制数据块,以允许Unity从另一个线程上的磁盘有效加载它们。

总而言之,AssetBundle就是一种资源包,让你能在运行时动态的加载卸载它,也可以灵活更新,即可以无需放在游戏本地,大大降低了包体大小。

NOTE
Unity提供了两种加载资源的方法(2018.2之后又新增一种)

  1. 通过放在本地特殊文件夹Resources下直接加载资源,通过Resource.Load()这个API加载就行,简单粗暴,非常适合新手,可以不用管资源怎么管理,加载就完事了。但有缺点,不利于拓展,也无法分平台发包以及从线上下载等。
  2. 本文要介绍的AB包方式,应该是目前比较通用的方案
  3. 2018.2版本后新增的可寻址方案Addressable,这个后续再写个博客

其实无论是用Resources或者Addressable加载方式,底层都是基于AssetBundle实现的,只是Unity引擎会自动做这步操作

官方文档:

https://docs.unity3d.com/Manual/AssetBundlesIntro.html​docs.unity3d.com

1. 工作流

  1. 设置资源的BundleName以及BundleVariant
  2. 打包AssetBundle
  3. (将AB包上传到服务端,若放在本地则可跳过)
  4. 加载AssetBundle
  5. 实例化AssetBundle中的资源
  6. AssetBundle的卸载

2. 打包AB包

设置资源的AssetBundleName和Variant

AssetBundleName与Variant介绍

将要打包成AssetBundle的资源设置AB包名字和变体名字

  • AssetBundleName: 即是该资源要打包进哪个AB包里面,若多个资源的AssetBundleName相同(且变体名Variant也相同)则这些资源会被打包到同一个AB包里,换言之,这个AB包包含了多个资源。

AssetBundleName不能包含"."这个特殊字符,会与variant产生冲突
使用/分隔符可以按层级建AB包,如AssetBundleName为A/B/C的AB包会被打包成A文件夹下的B文件夹下的名字为C的AB包

  • Variant: 类似后缀名的东西,称为变体,默认为.assetbundle,一般后缀大家都设置为.assetbunlde和.unity3d,那有人会用,这个有啥用。主要的用途应该用来做版本控制,即同种资源的不同形态下的加载,如不同语言包的同类型资源的加载,如可命名资源a的不同变体为http://a.cn,a.en等,根据不同的语言包加载不同的AB包。

参考链接:https://dev.twsiyuan.com/2017/05/unity-assetbundles-variants.html

AB包的分组方式

将哪些资源打包到一个AB包下是让人头疼的事情,就像你要把你的衣服放进衣柜里,总而言之就是整理的过程,而这种事情越早确定越好,到后期再更改就显得很麻烦。

Unity官方推荐的分类方式有以下几种:混合搭配才是王道

  • 按逻辑进行分类
    即按该资源被哪个功能应用到,同种功能用到的资源打到一个AB包内

    • 如将一个UI界面的所有图片纹理,布局文件打包到一个AB包
    • 将一个角色的所有动画,模型打包到一个AB包
    • 将一些公用的资源打包到一个AB包
  • 按类型分类
    将同一个类型下的资源打包到一个AB包中

    • 如将Windows和Mac平台下使用到的不同Shader资源分类打包
    • 将不同版本的Unity AB包进行分类打包
  • 同时使用的打包
    即考虑到哪些AB包可能会在某个时间段一起使用,则打包到同一个AB包中

    • 如某关卡下需要加载的所有资源一起打包
    • 某个场景下需要加载的所有资源,你应该尽可能将所有AB包依赖项都打包进来,避免加载其他依赖项

以下是官方给出的一些分类建议:

  • 将经常更新和很少更改的资源分开打包
  • 将基本会同时使用的资源打包,如模型和它用到的纹理,动画一起打包
  • 将一些很多资源会引用到的公共资源分开打包,避免重复打包
  • 如果两组几乎不可能同时加载的资源分开打,如Standard和High解析度资源分开打
  • 如果一次加载某个AB包经常用到少于50%其中的资源,则应该分开打包
  • 考虑合并比较小但经常一起使用的AB包
  • 如果某组资源只是同个资源的不同版本分类,使用variant打包(如不同语言版本的同个资源)

设置的方式

无非两种方案,一种手动,一种写脚本按一定规则变成自动

  • 手动方案,在资源的Inspector栏目手动添加/设置AssetBundleName和Variant

一键自动设置AssetBundleName和Variant
可设置规则,如按文件夹进行AB包的命名,同个文件夹下的资源打包到同一个AB包
设置AB包AssetBundleName和Variant的API如下:

AssetImporter.GetAtPath(filePath).SetAssetBundleNameAndVariant(bundleName, bundleVariant);

Build AssetBundle

前期准备做好了之后,这里就比较简单了,调用Unity的打包API就OK了,不过这里需要注意打AB包的一些参数设置,不同平台,不同的压缩方式等。

//方式1. Unity会遍历所有设置过AssetBundleName及Variant的文件进行全局打包
BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath,
BuildAssetBundleOptions.None, BuildTarget.StandaloneOSX);//方式2. 通过一个BuildMap打包指定的文件
AssetBundleBuild[] buildMap = new AssetBundleBuild[2];
buildMap[0].assetBundleName = "enemybundle";
string[] enemyAssets = new string[2];
enemyAssets[0] = "Assets/Textures/char_enemy_alienShip.jpg";
enemyAssets[1] = "Assets/Textures/char_enemy_alienShip-damaged.jpg";
buildMap[0].assetNames = enemyAssets;buildMap[1].assetBundleName = "herobundle";
string[] heroAssets = new string[1];
heroAssets[0] = "char_hero_beanMan";
buildMap[1].assetNames = heroAssets;BuildPipeline.BuildAssetBundles("Assets/ABs", buildMap, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);

压缩方式

  • BuildAssetBundleOptions.None
    使用LZMA格式压缩,这是序列化数据文件的单个压缩LZMA流(官方翻译的),LZMA压缩要求在使用整个AB包之前先对其进行解压缩。所以这种压缩方式的AB包体最小,但同时加载时间最长(永远的定律)。在第一次加载解压完成后,Unity会对他进行重新压缩为LZ4的格式,这种格式无需解压整个AB包即可读取里面的资源。这种方式一般使用在当加载某个AB包时就会使用到其里面所有的资源。如某个角色的AB包,里面的模型,动画,纹理等都会被同时需要,这种方案就比较适合。

通过UnityWebRequestAssetBundle加载的LZMA格式AB包将自动重新压缩为LZ4压缩,并缓存在本地文件系统上。而通过自己写的下载方案,则可以调用AssetBundle.RecompressAssetBundleAsync API重新压缩

  • BuildAssetBundleOptions.UncompressedAssetBundle
    这种方式的AB包完全没有压缩,所以包体是最大的,但同时加载的时候就比较快
  • BuildAssetBundleOptions.ChunkBasedCompression
    使用LZ4格式压缩,这种方式的包体比LZMA格式大,但无需解压完整个AB包就能读取里面的数据(LAMA就需要),LZ4使用基于块的算法,该算法允许AssetBundle分段或“块”加载。解压某些块就能使这些块中包含的资源先被读取,即使其他块的资源还未被解压。

NOTE
使用ChunkBasedCompression具有与BuildAssetBundleOptions.UncompressedAssetBundle差不多的加载时间,却具有减小磁盘大小的额外好处。

BuildTarget

打包平台,即要打包哪个平台的AB包,如Android平台则使用BuildTarget.Android,不同平台使用的AB包不同,无法跨平台使用。

输出文件夹

一般本地的AB包放在Unity特殊目录StreamingAssets下,通过Application.streamingassetpath读取

和Resources特殊目录一样,Unity会将该目录下的所有文件都打包,故需要特别注意,在打包不同平台的应用程序时,避免将其他平台的AB包一起打包,否则将大大增加包体大小。如Android的apk包就不应该确保StreamingAssets目录下只有Android平台的资源,其他平台的资源都是没用的,只会增加包体大小。

3. 生成的AB包文件

无论用何种方式打包AB包,最终生成的文件结构都是相同的。在同一输出文件夹下,生成的文件数目为该文件夹下 AB包数目*2+2,即假设有2个AB包打包输出到同一文件夹下,则在该文件夹下会生成6个文件。

每个AB包都会生成一份AB包本体文件(如上图的cube.a,若没有设置AB包Variant,则默认AB包后缀为.assetbundle),一份AB包的清单文件(上图的cube.a.manifest);

另外文件夹下会生成文件夹同名的两个文件,上图的StreamingAssets及StreamingAssets.manifest。StreamingAssets文件没有意义,StreamingAssets.manifest记录了一份该文件夹下AB包清单。

AB包的manifest则记录了AB包的一些依赖关系以及包含的资源清单,该清单仅用于查看,没有其他意义。

故构建AB包后真正有用的文件就是生成的AB包本体。

包打包和解析过程 unity_Unity AssetBundle 解析 (一)AB包介绍与构建相关推荐

  1. 包打包和解析过程 unity_Unity学习—资源管理概览

    本文介绍了 Unity 常用四种默认路径,以及 AssetDataBase.Resources.AssetBundle 和目前最新的 Addressable 四种资源管理方式 文中所有 API 均以版 ...

  2. PLSQL_解析过程及硬解析和软解析的区别(案例)

    2014-08-11 Created By BaoXinjian 一.摘要 Oracle硬解析和软解析是我们经常遇到的问题,所以需要考虑何时产生软解析何时产生硬解析,如何判断 1. SQL的执行过程 ...

  3. 通过输入ab包名和后缀名自动添加或修改ab包名(同一文件夹下的所有文夹都会被修改包括子文件夹)

    说明 temp = temp.Substring(temp.IndexOf("Assets")); 这段代码主要是获取的文件路径为完整路径,而AssetImporter.GetAt ...

  4. netgear路由器解包打包变砖过程

    注:本篇文章主要参考了 http://www.hackpluto.xyz/2020/09/27/netgear%E5%9B%BA%E4%BB%B6%E5%88%86%E6%9E%90%E4%B8%8E ...

  5. cname 别名记录 解析过程_云解析是什么?需要购买吗?

    域名解析:域名与 IP 地址之间是一一对应的,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析服务器(DNS)来完成.在互联网中标记唯一一台计算机使用的是IP地址,通过合法的IP地址,我们 ...

  6. MyBatis 源码分析 - 配置文件解析过程

    文章目录 * 本文速览 1.简介 2.配置文件解析过程分析 2.1 配置文件解析入口 2.2 解析 properties 配置 2.3 解析 settings 配置 2.3.1 settings 节点 ...

  7. Unity中AB包详解(超详细,特性,打包,加载,管理器)

    Unity中的AssetBundle详解 AssetBundle的概念 AssetBundle又称AB包,是Unity提供的一种用于存储资源的资源压缩包. Unity中的AssetBundle系统是对 ...

  8. 美团新一代渠道包打包神器walle

    背景: Android 7.0 中新增了 APK Signature Scheme v2 签名方式 如果Android Studio升级到 v2.2+,构建APK时默认使用的签名方式就是APK Sig ...

  9. [FairyGUI][Unity]加载FGUI打包成AB包的资源

    参考资料3 将发布后的文件打包为两个AssetBundle,即定义文件和资源各打包为一个bundle(desc_bundle+res_bundle).这样做的好处是一般UI的更新都是修改元件位置什么的 ...

  10. 内核源码包打包成rpm方式

    内核源码包打包成rpm方式 文章目录 内核源码包打包成rpm方式 第一部分,rpm包简单定制 一.rpm 制作前的环境准备 二.准备内核的源代码组件 1.下载地址 https://www.kernel ...

最新文章

  1. Select 多个表并且相关联转置
  2. LOJ-10096(强连通+bfs)
  3. HTTP、HTTPS、SSL总结
  4. 配置MongoDB复制集
  5. System进程(pid=4)占用80端口的解决方案
  6. SAP 电商云 Spartacus UI B2B checkout 点击 Continue 不能跳转到下一页面
  7. Windows系统上3种连接Docker虚拟机的方法
  8. 除了html 还有什么页面,HTML页面布局有哪些?
  9. Android Studio 0.1 gradle home的问题
  10. app用http3与服务器_mqtt服务器搭建以及客户端Paho安装使用
  11. Nsight Compute Profile Kernel无法定位源码问题
  12. linux 什么是SO文件
  13. 应用搬家:如何将软件从C盘迁移到D盘?
  14. 直播APP源码(干货):搭建直播平台的具体方案
  15. 3DMAX的渲染后期丨怎么在PS里P出真实感的灯光?
  16. 新鲜的字节跳动实习面经(Android开发岗),字节跳动面试分享
  17. PHP之Smarty
  18. Jquery图片轮播(连续滚动+突出显示)
  19. pandas之dropna()的用法
  20. 计算机逻辑功能测试及应用,逻辑门电路的逻辑功能及测试.doc

热门文章

  1. 直观讲解--RPC调用和HTTP调用的区别
  2. BIO,NIO的区别,使用场景。
  3. IOS-Run loop学习总结
  4. 资源 | 有了这些字体,你的设计也立即“高大上”起来。
  5. 使用树莓派3获取CPU温度
  6. 如何通过手机访问本地编写的html页面
  7. Linux文件系统的正确挂载方式
  8. Python的安装与配置
  9. javascript二级省市select联动菜单
  10. linux rpm