资产导入新管线:加速资源导入的坚实基础

资产导入新管线:加速资源导入的坚实基础

本篇为Addressable基础篇系列的第十节,是笔者对Unity官博的技术文章《The new Asset Import Pipeline: Solid foundation for speeding up asset imports》的译文。建议先阅读前九节内容,可以更好地理解本文。

导读

新的资源导入管线将会成为Unity 2019新建项目的默认选择。它旨在提高平台的切换速度以节省开发者的时间,并且给快速资源导入提供技术支持。同时,我们也会让Asset的管线导入能够服务更大型的项目。往下阅读,你可以了解更多关于这项新改进的详情,以及我们的出发点和考量。

不管什么时候,你把一个Asset放入你工程的时候,它其实并没有成为你工程的一部分,它必须等待Asset的导入管线发现它并且将它导入。Asset的导入管线必须能够正确地检测出项目状态,并且同时允许你通过APIs去查询这些状态。

早在2017年,Asset的导入管线就开始了重写,以便给新管线的实现铺上坚实的基石,同时也在解决一些用户在实际工作中上报的痛点。到了Unity 2019.3(现在在beta版中),新的Asset Import管线(也称为Asset Import Pipeline V2)将成为新项目的默认实现。旧的项目可以通过升级到最新的Asset导入管线来获得新技术带来的好处。

现在我们就来分享一下我们升级这个管线背后的一些想法。具体来说就是,我们希望在不改变APIs接口的同时来完成新管线的改造,这样开发者在升级的过程中就不必去重写脚本。

这里是Youtube的视频链接


实现更快的导入时间

日常的开发过程中会包含很多个不同的工作流。我们希望能够鉴别出这些耗时很高的问题,并且帮助他们解决这些问题。

资源导入就是一个非常耗时的问题。把源数据转换为Unity Editor或者某个指定平台所支持的格式,对开发者而言并不是能轻松把控的事情。比如,导入一个复杂的3D模型会花费大量的时间进行计算,同时如果这个模型包含动作,时间会成倍的增长。

为了解决这个问题,解决方案里需要包含三个关键概念并加以解决:

导入结果

Unity会把数据转化为何种格式,取决于你工程的目标平台。结果取决于GPU的格式,最终为PVRTC,ASTC or ETC。

这是因为大多数的文件格式都需要经过优化以节省存储空间。而在游戏或者任何其它的应用中,Asset都需要处理成可以供硬件立即使用的格式,比如CPU、图形或者音频硬件。

比如,当Unity导入了一个PNG格式的图像文件作为纹理,在运行时它并不会使用原始的PNG格式。取而代之的是,Unity会在工程的Library文件夹创建一个不同的,代表这个图像的另外格式。这个导入的版本就是引擎中纹理类所使用的,并且能够上传到GPU进行实时显示的。这个过程我们称之为导入结果

定论

我们需要知道,不管是你还是我,即便是硬件不相同,我们在进行相同资源导入的时候,得到的结果都应该是一致的。即对于给定的输入,获得相同的输出,我们称之为定论。

依赖追踪

Asset Import管线会追踪每个Asset的所有依赖项,并保存所有Asset导入版本的缓存。一个资产的导入依赖项指的是可能影响它导出结果的所有其它数据。这意味着,如果你的Asset Import的任何依赖项发生了变化,则该Asset的缓存版本就会过时,并且需要进行重新导入来正确反映这些变更。


新Asset Import管线介绍

导致导入资源花费大量时间的情况有很多,我们分析了一下,找到以下两个工作流的问题,并且给了一些解决方案:新工程导入和快速平台切换

新工程导入

当你第一次建立工程的时候,它的情况跟你把工程下的Library目录删掉如出一辙。这就意味着Assets工作目录下的每个Assets都需要经过Asset Import管线的处理。这是一项非常昂贵的操作。但是,如果我们能确保导入的过程在不同的机器上的正确性和稳定性,那么我们的导入器导入结果所耗费的时间就可以减少很多个数量级,当然这也取决于源Asset的大小和导入结果的大小。

我们通过使用新的Unity Accelerator来实现这一点,它缓存来自与云连接的任何人在云中的导入结果,从而允许您直接从服务器下载导入结果,而不必经历导入asset所需的繁重处理。

快速平台切换

直到Unity 2019.2(原始的Asset Import管线),Library文件夹里是都是由Assets的GUID命名的文件名。因此,从一个平台切换到另一个平台将使Library文件夹中的Import结果失效,导致它在每次切换平台时会被重新导入。


V1版本的资源导入管线

如果你不得不每天在平台之间来回切换多次,那么根据你的项目大小,这很容易就会占用几个小时。

当然,你们中的一些人已经找到了解决这个问题的方法,比如在你的机器上每个平台都有一个项目副本,但是这并不是很好的方案。

在新的Asset Import管线,我们删除了GUID到文件名的映射。由于追踪了特定Asset的依赖项,所以我们能够将它们全部散列起来,以便为Asset的导入结果创建一个修订版。这允许我们对每个Asset进行多个修订,这意味着我们不再把GUID绑定到文件名上。没有这样的要求,我们就可以拥有跨不同配置工作的导入结果。对于快速平台切换,我们可以在每个平台上都有一个导入结果,因此当你来回切换平台时,由于导入结果已经存在,从而使平台切换速度比V1版本快很多数量级。


V2版本的资源导入管线

可能的缺点

当你对Assets进行修改的时候,Unity会生成许多新文件来辅助新文件的生成。这会占用你的磁盘上更多的存储空间。但是,我们最终处理此问题的方式是在Unity重新启动的时候,删除未使用的ImportResults。我们会追踪每个平台的最新导入结果,以便在删除旧导入结果的同时仍然可以进行快速平台切换,从而帮助你释放一些磁盘空间。


怎么升级到最新的Assets Import管线

新的Asset Import 管线在Unity 2019.3beta上已经启用。如果有已存在的项目,可以使用编辑器中的Project Settings Window升级到新的“Asset Import Pipeline”:


选择Version 2会告诉编辑器,你现在希望此项目使用新的Asset Import管线,重新启动项目之后将会使用新的Asset Import管线代码重新导入它。这基本上与你删除了Library文件夹过程相同,但实际上没有删除它。切换到V2时,不会删除V1的导入结果,因为V2会创建自己的文件夹结构来存储其导入结果。
在Unity 2019.2或更老的版本中创建的项目,默认仍将使用V1版本。当第一次在Unity 2019.3中打开这样一个项目时,你会获得一个升级到新的Asset Import管线的选项。如果拒绝,项目将继续使用原始的V1版本。此外,所选版本存储在项目的EditorSettings.asset 文件中,因此可以对其进行版本控制。

新的工程用新的管线创建

使用Unity 2019.3或者更新的版本来创建工程的时候,默认使用V2版本的Asset Import管线。


更多的改进即将到来

在2019的哥本哈根Unite大会上,我们的团队分享了2个演讲。我的演讲是对这篇博文中所涵盖的主题的一个概括性的介绍,并且可以引导你你做自己的Asset管理策略。我的同事JonasDrewsen谈到了即将推出的旨在使Asset管线更加具有可扩展和确保项目稳定性的特性:https://youtu.be/VF-Qe-0zXlc

译者注
其实这篇文章和之前说的Unity的Asset的原理有些关联,也是Unity为了解决资源导入缓慢的一些解决方案。概括来说就是两个点:
1、以前的资源导入没能做到在不同的用户,不同的硬件上得到相同的结果,团队克服了这个技术难点之后,就可以利用云来加速。Unity Accelerator会缓存所有连接到云的导入结果,当有新的资源需要导入的时候,它从云里拉取别人编译过的,而不是自己再导一份。

2、切换平台的时候,以往的资源导入结果都是用GUID来存储的,所以当切换平台的时候,因为GUID不会变,所以只能通过改变内容来显现资源在不同平台的适应性,但是现在通过引入依赖项来解决,并且可以缓存不同平台的导入结果,当切换平台的时候就不用重新再导入了。

封面图来源于网络


感谢作者放牛的星星供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)

作者主页:https://www.zhihu.com/people/niuxingxing,作者也是U Sparkle活动参与者,UWA欢迎更多开发朋友加入U Sparkle开发者计划,这个舞台有你更精彩!