AssetBundle笔记

不管什么技术我们带着问题去看,可以很快的掌握它。
问题也是人生终极三问:我是谁?我在哪?我在做什么?
这里我把AssetBundle简称AB包。对应的是什么AB包?
AB包的工作原理?商业开发中AB包会遇到的问题以及解决方案?


一.什么是AB包?AB包的工作原理?

Unity引擎AssetBundle本质就是一种资源管理的技术,通过动态的加载与卸载资源,极大的节约游戏所占空间,2而且这种技术也实现了游戏发布后关于资源的后续更新与完善,所以这也是一种游戏的实时热更新技术。

AssetBundle是一个压缩包。它包含模型,贴图,预制体(Prefab),音频等资源,可以在游戏运行期被加载。

AssetBundle自身保存着相互的依赖关系。压缩包可以使用LZMA和LZ4压缩算法,减少包大小,更快的进行网络传输。具体到商业游戏中,可以把游戏后期运行的大量资源都放在AssetBundle里面,可以大幅减少安装包尺寸。

AssetBundle原理讲解:

在应用AssetBundle资源前,AssetBundle首先需要通过WWW下载到本地,然后AssetBundle在Unity引擎帮助下自动解压缩,这一过程也成为“内存镜像”。然后需要加载AssetBundle到内存区域中通过相关操作,最终创建具体的游戏对象才能显示与应用。

二.AB包的使用步骤?

总体来说AssetBundles可以分为以下四个部分:

第1:创建AssetBundles.

第2: 上传资源服务器端.

第3: 下载AssetBundles资源.

第4:加载与卸载AssetBundles资源。

---- 1.创建AssetBundles

总体来说创建可以分为二大步骤:

----------------- 1)标记AB包名称(命名)

首先定位需要打包与加载的资源,资源可以是任意类型(如:贴图,材质,音频,预设等)。在项目视图中点击资源,属性窗口下方中可以看到资源预览。在AssetBundle后面输入需要打包的“AssetBundle名称”。
image


这里有两个问题:

1.商业项目中有成百上千的资源需要打包,一个一个的去手工命名?

一套命名规范,并且依据此命名规范来编写一套自动打包命名的编辑器扩展脚本.

2.什么都能打包?那索性将C#脚本也打包了.热更新成了?为什么还要用Lua?

本人半桶水,这里就不强行解释了,以后姿势水平提升了在说,但是这里要说的是:不行!!!

AB包里包含的脚本,主程序里必须有一份,否则下载过来也会在挂脚本的地方出现叹号,而且通过测试,在AB里加了一个脚本,主程序不更新也没有用。可能打包时,AB里只包含了脚本的名字,一切以主程序里的脚本为准。AB打包脚本处理不完美,lua则是为解决这个问题出现的.

----------------- 2)Edior(编辑器扩展)下编写打包脚本

核心代码:

//打包核心API:
BuildPipeline.BuildAssetBundles("AB输出路径",BuildAssetBundleOption.None,BuildTarget.StandaloneWindows64).

这里有两点要说明:

1.压缩格式选择

BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩的包更小,但是加载时间更长。使用之前需要整体解压。一旦被解压,这个包会使用LZ4重新压缩。使用资源的时候不需要整体解压。在下载的时候可以使用LZMA算法,一旦它被下载了之后,它会使用LZ4算法保存到本地上。

BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快。

BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩,压缩率没有LZMA高,但是我们可以加载指定资源而不用解压全部。

注:使用LZ4压缩,可以获得可以跟不压缩相媲美的加载速度,而且比不压缩文件要小。

2.打包平台选择:

BuildTarget:选择build出来的AB包要使用的平台。

---- 2.上传资源服务器端

放在服务器完事,当然没那么简单, 整理中.JPG。

---- 3.下载AssetBundles资源

Unity提供了两种通过WWW类下载AssetBundle文件的方式方法。

----------------- 1)缓存机制下载

采用缓存机制下载的AssetBundle文件会存入Unity引擎的缓存区,通过WWW类的静态方法LoadFromCacheOrDownload实现下载。最大4G.

----------------- 2)非缓存机制下载

采用这种机制下载的AssetBundle文件不会存入Unity引擎的缓存区。(www.assetBundle)

---- 4.加载与卸载AssetBundles资源
----------------- 1)直接加载

assetBundle.LoadAsset();//通过指定assetBundle包名称加载资源。

----------------- 2)异步加载

assetBundle.LoadAssetAsync();//异步加载模式。与上述类似,但是加载过程不会同时阻碍主线程的运行,
这特别适合需要读取大尺寸资源,以及一次性读取多个资源的场合。

----------------- 3)全部加载

assetBundle.LoadAllAssets();//加载assetBundle中包含的所有资源对象。

----------------- 4)卸载

www==null或www.dispose()释放对象资源。

assetBundle.Unload(false);//释放assetBundle内存镜像。

assetBundle.Unload(true);//释放assetBundle内存镜像且销毁内存镜像对象。

Resource.UnLoadUnusedAsset();//释放没有引用的资源

Resource.UnLoadAsset(Obj);//释放指定资源。

GameObject.Destroy();//释放GameObject复制体

---- 5. AssetBundle依赖关系

Unity打包的时候会自动处理依赖关系,并生成一个.manifest文件,这个文件描述了assetbundle包大小,CRC验证,包之间的依赖关系等。

Unity的依赖关系处理并不是万能的,对一些复杂处理还是需要研发人员手工处理。

三.商业开发中遇到的问题以及解决方案?

---- 1. 批量打包命名问题

商业项目中有成百上千的大量资源需要(批量)打包处理,不可能手工维护方式给每个资源添加assetbundle包名称。

解决方案:开发专门标记脚本,自动给制定目录下所有合法资源文件(预设,贴图,材质等)添加标记。
这里我提一个学到的命名规范:
对于一个大型游戏可能含有海量资源,而移动端设备一般内存与性能价低(相对于pc),为了权衡起见,我们一般对大量的AB包按照"场景”进行分类,也就是说一个游戏在场景开始前只加载本场景用到的资源AB包即可。

资源包名的命名规则:
我们对于资源包名的命名规则就确立为:“场景名称”+"功能文件夹名"即可。结合Unity规定,我们进一步确立为:
包名称=“场景名称/功能文件夹名”。

---- 2. AssetBundle使用过于复杂

AssetBundle包的商业应用涉及很多步骤:AB包的加载,AB包的依赖关系(要求:不遗漏,不重复),资源的提取与释放等。手工以及简单写代码实现功能,将是一项繁重海量工作,效率低下,且容易出错。

解决方案:

1:通过写专门的脚本读取Unity自动创建.manifest文件。自动分析与维护AssetBundle包之间的依赖关系,使得包的依赖关系可以实现循环依赖,自动化加载。

2:开发针对AssetBundle的专门框架。按照一定严格流程解决AB包加载,复杂依赖,资源提取释放等事宜,尽可能让最终使用框架人员,只关心输入与输出结果部分,屏蔽内部复杂性。


先这样,有点水,这里面有大量的代码实现没弄。抽个空把这些补齐。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值