失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 包打包和解析过程 unity_Unity AssetBundle 解析 (一)AB包介绍与构建

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

时间:2021-11-19 13:11:39

相关推荐

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

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

介绍

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

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

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

NOTE

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

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

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

官方文档:

/Manual/AssetBundlesIntro.html​

1. 工作流

设置资源的BundleName以及BundleVariant打包AssetBundle(将AB包上传到服务端,若放在本地则可跳过)加载AssetBundle实例化AssetBundle中的资源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的不同变体为,a.en等,根据不同的语言包加载不同的AB包。
参考链接://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包介绍与构建》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。