本文基于官方文章编写,原文地址
干啥的
AssetBundle
是在编辑模式下创建的一系列文件,它们可以被动态加载到Unity运行时中。所以它支持流式加载和异步载入模型,纹理,声音甚至是整个场景,除了唯一的例外:脚本。
优点
- 动态加载释放一个资源。
- 发布新的DLC。
- 可定制的下载需要的部分。
- 根据用户的位置,语言,喜好配置不同的资源包。
- 在不重装的情况下修复、更改、升级新资源。
缺点
- 它完全是下载的,所以如果其中混入了无用资源,会造成存储和带宽的双重浪费。
特性
有些需要注意的地方:
AssetBundle
会被完整的下载和缓存。AssetBundle
中的Asset可以根据需要载入。- 在Bundle中的Asset可以依赖其他Asset
- 在Bundle中的Asset可以和其他Asset共享依赖
- Each AssetBundle has some technical overhead, both in the size of the file and the need to manage that file.
AssetBundle
需要区分目标平台
当组织AssetBundle
时,需要在过多的、却需要追踪版本的小Bundle,和很少的、却包含冗余信息的大Bundle之间做取舍。
另外,AssetBundle
的内容会被针对目标平台编译和优化,因此它需要区分平台编译。
依赖
通常说来,一个资源都跟其他资源有关联,有的引用了好几个材质,有的共用一个材质。因此需要通过一个组织来管理。
资源依赖不会丢失。如果一个资源未被任何Bundle标记,依赖资源会在生成时跟随选中的Bundle自动打包。这可以很方便的防止丢东西,然而会导致资源重复。例如:
1 2 3 | 现在有两个石头使用相同的材质。 如果它们被分开到不同的Bundle中,那么材质就是隐式的包含。 它会被重复打包两次! |
这种情况下,就产生了冗余数据,而且也破坏了共享资源,因为每一个Bundle中持有了自己的材质。为了避免这种情况,材质需要精确的被指定Bundle。它可以独自作为一个材质,或者与其他资源共用一个Bundle,无论哪种情况,这个石头打的Bundle要依赖于材质的Bundle。
依赖和其他信息被存储在Manifest文件中。这个文件十分像一个项目AssetBundle
的内容表。当打包资源时,Unity生成大量的文件。这些文件的数据信息都被存入Manifest中。每个平台都会有且只有一个Manifest,它列出了从项目中针对当前目标平台创建的所有AssetBundle
,以及它们的所依赖的存储和追踪信息。有了这个Manifest,可以查询到所有的Bundle文件。
Bundle有个AssetBundle Variants
设置,它被用来支持定制化的参数。与预定义宏类似,它可以对一个单独对象重映射项目中不同的资源。这可以灵活控制语言、地区、或者用户偏好。AssetBundle Variants
能持有资源对象所需的配置参数,并从依据这个值映射到其他需要的对象上。
总结一下,AssetBundle
是包含模型、材质、纹理、场景等资源的文件。它由Unity在编辑时创建,并可以在运行使用。它可以加载本地或远程的资源,它也有配置值,根据这个值能够根据用户偏好映射场景中的对象。
使用
由于能够远程下载,跟包走的预存AssetBundle并没有太大的意义。只有在无法下载内容时,默认语言和本地化的备用包才会被使用。同样包中区分平台的资源也没有意义,因为在打包时就配置过了。
简单的工作流:
- 在编辑器中组织和设置AssetBundles.
- 打包AssetBundles.
- 上传AssetBundles到外部存储.
- 在运行时下载AssetBundles.
- 加载AssetBundles中的资源.
设置 AssetBundle
选中资源后,可以在Inspector中设置对应的AssetBundle分类,如下图所示:
所有资源必须是小写字母,支持层级命名,例如:aaa/bbb
设置变量
通过设备变量,可以实现定制化的资源控制例如,variant
区分了相同资源的不同版本,所以它可以为同一个资源提供不同的解决方案:SD资源和HD资源,或者不同面数的模型。当然它也支持不同的语言,区域,主题。我们可以指定文件夹为对应类型:
由于想要整体替换资源,对应目录下文件需要完全一致。因此在这个粒度下,需要完全覆盖所有资源。
使用AssetBundleManager
AssetBundle Manager
是为Unity3d提供高级接口的资源管理插件,可以在这里下载。然后将目录放置到Asset目录下即可,成功后如图所示:
点击Simulation Mode
允许编辑器在没有编译资源时直接使用AssetBundle。当这个模式激活时,编辑器会查看注册到AssetBundle的资源,并引用它们的目录,假设它们在AssetBundle中,这样可以极大的简化开发流程。
为了测试Variant
,AssetBundle需要被构建和部署。此时需要用到Local Asset Server
。当它开启时,AssetBundle
必须被构建和放置到Assets
的同级目录AssetBundles
中:
有了Bundle,就跟外网环境相同了。
运行时使用
AssetBundle Manager
的API包括:
- Initialize() Initializes the AssetBundle manifest object.
- LoadAssetAsync() Loads a given asset from a given AssetBundle and handles all the dependencies.
- LoadLevelAsync() Loads a given scene from a given AssetBundle and handles all the dependencies.
- LoadDependencies() Loads all the dependent AssetBundles for a given AssetBundle.
- BaseDownloadingURL Sets the base downloading url which is used for automatic downloading dependencies.
- SimulateAssetBundleInEditor Sets Simulation Mode in the Editor.
- Variants Sets the active variant.
- RemapVariantName() Resolves the correct AssetBundle according to the active variant.