AssetBundle 是一个存档文件,其中包含特定于平台的非代码资源(比如模型、纹理、预制件、音频剪辑,甚至整个场景),Unity 可在运行时加载这些资源。AssetBundle 可以表示彼此之间的依赖关系;例如,一个 AssetBundle 中的材质可以引用另一个 AssetBundle 中的纹理。为了提高通过网络传输的效率,可以根据用例要求(LZMA 和 LZ4)选用内置算法选择来压缩 AssetBundle。
AssetBundle 可用于可下载内容(DLC),减小初始安装大小,加载针对最终用户平台优化的资源,以及减轻运行时内存压力。
为任何独立平台构建的 AssetBundle 只能在该平台上加载。例如,在 iOS 上构建的 Bundle 与 Android 不兼容。其中一个原因是着色器、纹理和其他类型的数据基于 BuildTarget 内置到特定于平台的格式中。
构建或重新构建 AssetBundle 时,通常使用单个 API 调用同时构建项目的所有 AssetBundle。通常最好不要单独构建或重新构建,因为同时构建时,Unity 编辑器会决定如何在每个 AssetBundle 中引用或嵌入内容,而这可能取决于其他 AssetBundle 中包含的内容。如果您是高级用户,了解项目中 AssetBundle 之间的引用和依赖关系,这将是例外情况,因为有时您可能只需要构建项目 AssetBundle 的子集。
因为用来加载 AssetBundle 的 API 设计得很简单,并不考虑 AssetBundle 中数据的表示方式。但是,了解结构可能很有用,尤其是在使用工具提取或检查 AssetBundle 的内容时。
AssetBundle 是一种容器文件格式,类似于 zip 文件。它有一个二进制格式的头文件,并在其中嵌入了其他文件。这些附加的文件有两种类型:
AssetBundle 文件始终包含一个序列化的 AssetBundle 对象。此对象的作用类似于 AssetBundle 内容的目录。这是通过代码进行交互的对象,用于从特定 AssetBundle 存档加载资源,使用 Addressables API 从 AssetBundle 加载资源时,也会在内部使用此对象。
在构建 AssetBundle 时,所含的对象会被序列化,此时将用到您在构建时所用的 Unity 编辑器版本的定义,以及在构建的项目中定义的 C# 类型。每种类型的信息都记录在 AssetBundle 中称为_类型树 (Type Tree)_ 的结构内。此类型信息在一定程度上影响 AssetBundle 的大小,不过,若在构建时播放器的版本与编辑器版本不匹配,启用加载这些对象将至关重要。对于许多 Unity 功能,类型相当稳定,并且仅在版本之间发生细微变化,因此向后兼容性支持运行良好。但是,在 Unity 功能发生重大变化的情况下,加载旧数据可能无法达到较新版本中的预期结果。在这种情况下,必须使用新版 Unity 重新构建 AssetBundle。
Unity 不支持向前兼容,因此,如果将使用新版 Unity 构建的 AssetBundle 加载到使用旧版 Unity 构建的播放器中,可能会在加载内容时出现问题。
注意:默认情况下,用于构建文件的 Unity 编辑器版本包含在 AssetBundle 头文件中。此信息在调查向后兼容性问题时非常有用。但是,如果在对编辑器进行小规模升级后重新构建项目,也可能导致 AssetBundle 不必要地重新构建,并导致不必要的客户端下载。为了避免这种情况,可以排除编辑器版本,请参阅 BuildAssetBundleOptions.AssetBundleStripUnityVersion。
AssetBundle 不包含程序集,也不用于分发新的 C# 类或更改现有类。它是包含已编译程序集的运行版本。这意味着要发布代码更改,必须重新构建并重新分发游戏或应用的主构建。
但是,您可以使用 AssetBundle 来分发新对象,这些对象将作为类实例编译到运行版本中,例如游戏的新项目。
例如,AssetBundle 可以包括 ScriptableObject 资源。从 AssetBundle 加载该资源时,Unity 将根据程序集名称、命名空间和类名称查找匹配的类定义。它将创建一个对象作为该类的实例,并使用序列化值设置对象的字段。
如果对象是基于类的旧定义被序列化,Unity 将根据字段名称和类型树中记录的其他信息,使用向后兼容性支持匹配任何可匹配的字段。
脚本通常使用条件编译来指定特定于平台的代码。例如,使用 UNITY_STANDALONE、UNITY_IOS 和 UNITY_ANDROID 等脚本符号。如果未在某些目标上编译类或结构体的字段,则 AssetBundle 中的对象序列化将不包含这些字段(也不会包含在类型树中)。这是必须为每个目标平台重新构建 AssetBundle 的另一个原因。
有两个受支持的 API 可用于为 Unity 构建 AssetBundle:
BuildPipeline.BuildAssetBundles、AssetBundle 和 UnityWebRequestAssetBundle。本手册的本节中描述的就是此功能。但是,此方法的级别很低,例如,这需要您了解资源依赖关系,自行确定捆绑包分配,编写自己的构建脚本。