一、初识AB包
AssetBundle是将资源用Unity提供的一种用于存储资源的压缩格式打包后的集合,它是对资源管理的一个扩展,可以动态地加载或者卸载,并且大大地节约了游戏所占的空间,即使是已经发布的游戏也可以用其来增加新的内容。因此,动态更新、网页游戏、资源下载等都是基于AssetBudle系统的。
二、具体开发步骤
- 创建AssetBundle,开发者在Unity编辑器中通过脚本来将所需的资源打包成AssetBundle文件。
- 上传至服务器。开发者创建好AssetBundle文件后,可通过上传工具将其上传到游戏的服务器中,使游戏客户端可以通过访问服务器来获取当前所需的资源,进而实现游戏的更新。
- 下载AssetBundle。游戏进行时,客户端会将服务器上的游戏更新所需的AssetBundle下载到本地设备中,再通过加载模块将资源加载到游戏中。Unity提供了相应的API可供使用来完成从服务端下载AssetBundle。
- 加载AssetBundle。AssetBundle 文件下载成功后,开发者通过Unity提供的API可以加载资源里所包含的模型、纹理图、音频、动画、场景等,并将其实例化来更新游戏客户端。
- 卸载AssetBundle。在Unity中提供了相应的方法来卸载AssetBundle,卸载AssetBundle可以节约内存资源,并且保证资源的正常更新。
三、AB包的打包
只有Assets面板下的资源文件才能被打包到AB包中,所以有些模型资源先被制作成Prefab预制体才行,在Inspector面板底部有AssetBundle的创建工具,空的AB包可以通过菜单选项“New”来创建。然后可以BuildAssetBundles,也就是创建好之后需要导出,这一过程需要编写代码实现。
四、AB包的下载
两种下载方式
缓存机制和非缓存机制
非缓存方式所下载的资源文件不会被写入Unity引擎的缓存区,而缓存机制下下载的资源文件会被写如Unity引擎的缓存区中。
非缓存机制通过创建一个WWW实例下载AssetBundle文件,采用此种方式下载的AssetBundle的文件不会存入缓存区。
缓存机制通过WWW类下的LoadFromCacheOrLoad接口来实现AssetBundle的下载,通过缓存机制下载的AssetBundle会被存储在Unity的本地缓存区中。下载前系统会在缓存目录中查找该资源,当下载的数据在缓存目录中不存在或者版本较低时,系统才会下载新的数据资源替换缓存中的原数据。
五、AsserBundle的加载和卸载
AssetBundle下载完成后,并不能直接被使用,需要将AssetBundle加载到内存中去并且创建成具体的文件对象,这个过程就是AssetBundle的加载,需要开发者编写代码实现,并且无论是在下载还是加载的过程中,AssetBundle都会占用内存。
1、如何加载?
将AB包下载到本地客户端后,就等于把硬盘或者网络的一个文件读到内存的一个区域,这是只是AB包内存镜像数据块,需要将AB包中的内容加载到内存中并且实例化AB包文件中的对象,Unity提供了三种不同的方法从已经下载的数据中加载AB包。
- AssetBundle.LoadAsset
- AssetBundle.LoadAssetAsync
- AssetBundle.LoadAllAssets
具体用法和意义请读者自行去查阅资料。
2、卸载AB包则是:
AssetBundle.Unload(XXX)
这个方法是使用一个布尔值参数来告诉Unity是否要卸载所有的数据(包括加载的资源对象)或者只是已经下载过的被压缩的资源数据。
1、如果是AssetBundle.Unload(false)
false是指释放AB包文件的内存镜像,不包含Load创建的Asset内存对象。
2、如果是AssetBundle.Unload(true)
true是指释放那个AB包文件内存镜像并销毁所有用Load创建的Asser内存对象。
Unity仅可以将一个特定的实例化AB包在应用程序中加载一次,如果加载一个已经加载并且没有被卸载的AB包,Unity会报错。所以对于不再使用的AB包,或者卸载或者避免下载,这也就解释了AB包为什么一般需要被卸载。
六、管理依赖
任意Bundle中的资源都可能会依赖于其它的某个资源,比如几个不同的模型都使用了某张贴图。
如果一个共享的依赖资源被包含在每一个使用它的对象中,那么当这些对象被打包时,此部分共享的资源就会被多次打包,这会造成内存的浪费。为了避免这种浪费,需要将共享的资源打包到一个单独的AB包,然后让两个模型所隶属的AB包分别依赖于该AB包。
通过这样的方法,该依赖资源仅被打包一次,从而起到节省游戏资源的效果。现在Unity会自动判断并处理所打包的资源之间的依赖,开发者仅需将所有资源一次性打包到指定的文件夹下,相关依赖的管理都有系统自动解决,不再需要手动处理。
七、存储和加载二进制文件
AB包可以把Unity3D中的文件或者资源导出为一种特定的文件格式(.Unity3d),导出的特定格式的文件能在需要的时候加载到场景中去。
如果想要保存以“.bytes”为扩展名的二进制数据文件,需要在Unity中将该文件保存为TestAsset文件,然后才能对AB包进行加载,在通过检索二进制文件数据来实现。
八、在资源中包含脚本
Unity中也可以把脚本打包成AB包,但要注意它与普通资源文件的处理方式不同,并且实际上也不会执行代码。如果你想在AB包中包含代码,就需要将脚本预编译并上传到网站中,摒弃引用Reflection类来实现。