一、AssetBundle是什么?
AssetBundle是Unity pro提供的一种用来存储资源的文件格式,通过把一系列的资源文件或者场景文件使用LZMA压缩方式得到(不清楚LZAM的自行百度)。
AssetBundle 由 Unity 编辑器在编辑环境中(enit-time)创建,可以被用在项目的运行环境中(run-time)。可以存储任意一种Unity引擎能够识别的资源(也就是asset,脚本除外),如模型文件(models)、材质(materials)、纹理(textures)和场景(scenes)等等,同时,AssetBundle也可以包含开发者自定义的二进制文件,只需要将自定义文件的扩展名改为.bytes,Unity就可以把它识别为TextAsset,进而就可以被打包到AssetBundle中。
AssetBundles 可以预缓存(pre-cached)和存储在本地,这样在运行时就可以立即加载它们。但是 AssetBundles 技术的主要的目的是在需要的时候能够从远端的服务器上按需请求特定的资源,并加载到游戏中。
AssetBundle的特点总结就是:压缩(缺省)、动态载入、本地缓存;
唯一的例外是,脚本资源是不被允许的(只能保存资源文件对脚本的引用关系)。
二、AssetBundle VS Resource
从本质上来说,利用Unity开发的游戏加载传统资源和AssetBundle本质上并没有什么区别,都是解析各种资源构成应用场景,但是我们都知道,一但Unity应用打包过后,资源文件夹(Resource文件夹)就消失了,都被打包进了应用程序里面.
但AssetBundle作为Unity官方推崇的资源更新方案,与传统的Resource差异如下:
- Resource放在Resources目录下,resources.assets文件,单个文件有2GB限制,首次必须全部下载;
- AssetBundle创建需要通过Editor脚本创建,支持动态下载,是Unity Web Caching License唯一可以缓存的内容。
三、AssetBundle的依赖结构
一个通俗点的例子,你有一个Cube你给与了他一个蓝色的材质(blueMaterials),你在加载Cube之前必须先加载了blueMaterials,否则就会材质丢失,即Cube依赖blueMaterials,实际中模型往往非常复杂,那么依赖关系对应的也更加复杂。
所以依赖关系的处理是AssetBundle的一个重要的部分,好在新版本(5.x及以上)中更新AssetBundle系统,可以更好的帮我们处理这些依赖关系。
四、AssetBundle的适用平台与跨平台性
AssetBundle适用于多种平台,包括网页应用、移动应用、桌面应用等,可以动态更新,但不同平台所使用的AssetBundle并不相同,在创建离线AssetBundle的时候需要通过参数来指定目标平台,相容关系如表所示:
Standalone | WebPlayer | IOS | Android | |
---|---|---|---|---|
Standalone | √ | √ | √ | √ |
WebPlayer | √ | √ | ||
IOS | √ | |||
Android | √ |
五、AssetBundle的打包策略
实际的应用开发中,肯定不可能把所有资源打包成一个AssetBundle包,如何处理这些资源,分类打包,便于更新和维护是一个值得深入思考的问题。
每一个 AssetBundle 都有一些技术开销。AssetBundles 是一些封装资源的文件。这种封装会增大了 AssetBundle 的整体大小,尽管这种大小的增加不会太明显,而且是可测量的。当组织 AssetBundles 时,是更多的小的 AssetBundles 还是更少的大的 AssetBundles 呢?这是需要我们根据自己的项目的实际情况来好好权衡的。更多的小的 AssetBundles 会面临更多的跟踪和创建相关的开销,太少的 AssetBundles 会使单个AssetBundle 本身的大小变大,也会导致它们可能包含一些冗余的数据,且不便于维护。
六、AssetBundle的工作流程
- 创建AssetBundle;
- 上传到Server;
- 游戏运行时根据需要下载(或者从本地cache中加载)AssetBundle文件,这几乎就是热更新的核心所在;
- 解析加载Assets;
- 使用完毕后释放;
七、远端Server的AssetBundle下载
Unity引擎提供了两种方式从服务器下载AssetBundle文件,分别是缓存机制和非缓存机制。
缓存机制的主要特点就是下载AssetBundle的时候,该接口会先在本地缓存中查找该文件,看其之前是否被下载过,如果下载过,则直接从缓存中加载,如果没有,则从服务器尽享下载。而非缓存机制通过创建一个WWW实例来对AssetBundle文件下载,下载后的AssetBundle文件将不会进入Unity的缓存区。使用这种方法每次都会从远端服务器下载。