Renderu.com
10.1 K帖子
68.3 K关注
33.4 M访问
Alex Rowan

Unity 6.6 让 AssetBundles 退役:Slime Rancher 2 的增量构建从 32 分钟缩短到三分钟

软件

Unity 在 6.6 版本中推出了 content directories——一种打包和加载内容的新方式,引擎开发者直接将其称为 AssetBundles 的替代品。最主要的区别在于,运行时现在寻址、加载和卸载的是单个构件,例如某个具体的网格或贴图,而不再是整个 bundle。各团队多年来绞尽脑汁琢磨分组策略的 bundle 划分,不再是一项设计决策。

Unity 给出的数据来自一个真实项目:从 Addressables 迁移到 content directories 的 Slime Rancher 2。增量构建从 32 分 16 秒缩短到 3 分 4 秒,全新构建从 58 分 6 秒缩短到 37 分 13 秒。游戏构建体积从 4 GB 瘦身到 2.88 GB,加载时间从 45 秒加快到 30 秒,约快了三分之一。测试在搭载 M5 Max 的 MacBook Pro 上、于 Unity 6.6 Beta(6000.6.0b10)中完成。

Unity 6.6 отправляет AssetBundles на покой: инкрементальная сборка Slime Rancher 2 ускорилась с 32 минут до трёх
资源的异步加载:Slime Rancher 2 的加载时间从 45 秒降到 30 秒。图片:Unity

为什么 bundle 作为加载单位不再够用

AssetBundle 是分发、存储和加载中不可分割的单位。依赖关系在 bundle 层级被追踪,加载和卸载也必须整体进行。由此衍生出全部配套工作:手工把资源分配到各个组、追踪依赖链、与多个 bundle 之间公共资源的重复作斗争。

content directories 的构造完全不同。Unity 采用了内容寻址存储方案——与 git 的底层思路相同:每个内容文件都以自身内容的哈希来命名和寻址。去重从开发者的任务变成了格式本身的属性。不过构件之间并不通过哈希相互引用,而是使用稳定的标识符——否则修改一个文件就会让整条链上的哈希连锁变化;标识符与哈希的对应关系保存在构建清单中。

哪些内容要进入构建,现在不再靠给每个资源打标记来指定,而是由根资源决定,也就是普通的 ScriptableObject。依赖会被自动带入,并按单个资源而非按 bundle 追踪。代码中出现了 Loadable<T>

类型——引擎层级的可加载引用:声明一个形如 Loadable<Mesh> bodyMesh 的字段,随后调用 bodyMesh.Load();单个资源的加载与卸载既可以同步进行,也可以通过 async/await 异步进行。被 Loadable 引用的对象会进入构建,但在被请求之前不会加载到内存。加载本身在读取和反序列化两个环节都完全异步,使用各平台的 async API;其底层是 2022 年在 DOTS 中出现的内容文件格式。
Unity 6.6 отправляет AssetBundles на покой: инкрементальная сборка Slime Rancher 2 ускорилась с 32 минут до трёх
把 Addressables 项目转换为 content directories。图片:Unity

已经在用 Addressables 的人该怎么办

Unity 没有破坏现有项目。content directories 与 Addressables 包兼容,后者仍然是组织内容的界面,现有项目可以转换到新的后端:Slime Rancher 2 的迁移没有改动一行代码。转换流程以及各种方案的对比,都写在 Addressables 的文档里。

真正改变的是「究竟需要标记什么」这一思路。Unity 会自动把 Loadable 引用到的资源纳入构建,并自行清除重复项,因此不再需要为公共依赖单独建 bundle。文档建议为整个项目只创建一个根资源;如果代码要通过字符串键加载大量资源,则建议用 ScriptableObject 充当资源列表,而不是建立大量根资源。

Unity 6.6 отправляет AssetBundles на покой: инкрементальная сборка Slime Rancher 2 ускорилась с 32 минут до трёх
content directories 无需重写代码即可嵌入现有的 Addressables 配置。图片:Unity

需要提前知道的限制

在 6.6 中,content directories 只适用于本地内容,即随播放器一同分发的那部分。远程分发和安装后的补充下载,仍然需要 AssetBundles 或自研机制。完整的「空中」细粒度分发,Unity 承诺放在 Unity 7 一代,细节将在 2027 年公布。

  • BuildUsage
API 与 content directories 不兼容:使用它的资源需要修改,官方建议用 Project Auditor 排查问题;
  • 存在循环依赖的资源会被粘合成一个可加载块——Unity 会给出警告,而如果循环的总体积超过 64 MB,构建就会失败;
  • 全新构建有可能比 AssetBundles 的构建更慢;
  • 在同一个项目里混用 AssetBundles 和 content directories,会导致公共依赖被构建两次;
  • 每次构建都是自足的:如果两个 content directory 引用同一个资源,各自都会包含一份副本。
  • content directory 在运行时注册,此后其中的资源即可使用;场景同样通过可加载引用接入。详细内容见 Unity 关于 content directories 的官方文档。

    Unity 为什么偏偏在此时更换地基

    content directories 看上去是整个内容技术栈换了支点,而不是 6.6 的一项单独功能。AssetBundle 的局限在 Addressables 的设计中也清晰可见:使用这个包的相当一部分工作,实质上是在弥补 bundle 不可分割这一点。一旦基础单位变得原子化,技术美术和构建工程师的部分惯常工作——按组划分、追查重复、手工管理依赖链——自然也就失去了意义。

    这个方向与整个行业转向内容寻址存储和增量构建的趋势一致:同样的原理早已在版本控制系统和构建缓存中运转,而在大型项目里,它的收益首先体现在迭代时间上。Slime Rancher 2 这个例子中增量构建缩短到十分之一,冲击的与其说是最终构建,不如说是每天修改与验证的循环——而团队的工时正是花在这上面。

    Addressables 并不会就此消失:从迁移方式来看,这个包仍然是面向用户的界面,而 content directories 占据了它下面的位置。考虑到 Unity 把远程分发绑定在 Unity 7 一代的新地基上,迁移到这套后端很可能会逐渐成为细粒度内容补充下载的前提条件,而今天还靠手工划分 bundle 度日的项目,值得提前研究一下转换事宜。

    为什么 AssetBundles 直到现在才被送去退役:来自 Godot 和 Unreal 的压力、Addressables 积攒下来的痛点,还是 John Riccitiello 离任后的路线转向?

    0
    相关新闻:
    免费插件 Hardcraft 读取 CAD 导出的结构,并据此在 Blender 中生成游戏网格
    Obsidian 转归 Bethesda 管理:Fallout 仍由 Bethesda Game Studios 主导
    Undead Labs 脱离 Xbox,成为员工持股工作室——代价是大规模裁员
    85.8%的日本游戏开发者使用生成式AI:一年间比例显著上升
    评论:1
    发布日期 所有语言 只是英语