随着游戏规模和资产精度的提升,以及Nanite等技术的应用,项目工程规模急剧膨胀,达到数百G乃至上T的量级,完整拉取的耗时可能数小时。
而每个人在实际开发中,能够用到的资源只占其中的一小部分,所以怎么样减少工程拉取量级,使工程轻量化是需要优化的问题。
在UE5中,官方推出了虚拟资产(VirtualAssets)机制,与P4结合能够做到这一点。
本篇文章会介绍UE5中虚拟资产的配置流程、资产的虚拟化过程与加载代码分析,以及断网可用性的测试。
注:Virtual Assets只能与P4版本控制结合,不支持Git与SVN。
前言
Virtual Assets是一项资产元信息与数据剥离的方案,可以把传统UE项目中的uasset
拆分为uasset
+payload
的形式,对于无需加载的资产而言,只需要虚拟化后的uasset
,它不包含实际的资产BulkData,当实际访问到该资产时,再从Server上把资产的Payload数据拉取下来,从而实现减少拉取的工程规模的目的。
在Epic自己的数据中,虚拟化的数据也非常好(Texture是大头,仅贴图虚拟化后就可以减少总体60%的大小):
开启虚拟化
按照官方文档介绍,VirtualAssets默认处于关闭状态,需要添加下面的配置文件手动开启:
1 | [Core.ContentVirtualization] |
需要注意DepotRoot
需要指定的是虚拟化文件的存放路径,比如存储在//remote_depot/branches/Project/Content/VirtualAssets/
,它可以不放置在Content
目录下,也不需要拉取该目录。
虚拟化/提交流程
在进行前面的配置之后进入引擎,连接P4,就可以为资产进行虚拟化了。引擎支持在CheckIn时自动执行虚拟化过程。
在引擎内连接p4:
对资产进行check-in,就会自动执行资产的虚拟化,并提交至P4:
提交完之后,可以在p4上看到提交记录,以及每个hash与资产的对应关系:
Description
中的内容是:前6个字符是路径(每两个字符是一级路径),后面的部分是实际的hash值。
在引擎中可以查看Has Virtualized Data来资产是否进行过虚拟化:
在p4中设定的Depot
目录下就会新增upayload
文件了:
upayload文件的存储方式只按照hash化命名,并没有按照类型、路径之类的进行区分。
举个例子,Texture和StaticMesh的payload只看路径和名字是完全无法区分的:
虚拟化之后,Asset的大小会有明显变化(几MB到10K量级):
除了在Editor内CheckIn之外,引擎还提供了一个工具UnrealVirtualizationTool来批量虚拟化和逆转换。
执行参数:
1 | Usage: |
仅虚拟化部分资产
禁用资产类型
如果想要某种类型不参与虚拟化,引擎提供了配置支持。
在DefaultEngine.ini
中控制某种类型的资产不参与虚拟化:
1 | TArray<FString> DisabledAssetTypesFromIni; |
可以在Core.ContentVirtualization
或Core.VirtualizationModule
的Section下添加:
1 | [Core.VirtualizationModule] |
在启动时就会有如下输出:
1 | LogVirtualization: Display: Virtualization is disabled for payloads of the following assets: |
在引擎内提交贴图时就不会自动进行虚拟化了。
但引擎目前(UE5.6.0)仅提供了DiabledAsset
的配置,相当于黑名单。并没有提供类似白名单的选项,这个可以自己改引擎代码扩展。
禁用路径/资产
如果想要某些路径/资产控制是否虚拟化,可以把下面的配置放入DefaultEngine.ini
中:
1 | [/Script/Virtualization.VirtualizationFilterSettings] |
这两项配置会在FVirtualizationManager::ShouldVirtualizePackage
中使用:
注意事项
- 不能把
Saved/VASubmission
目录标记为p4ignore
,如果加了Saved/
也会把它过滤掉。 - 资产虚拟化之后,如果删除引擎内的资产,对应的虚拟化文件并不会被删除,是一直累加的。
- 虚拟化文件会自动去重,比如同一张图片的重复导入,不会生成多份
upayload
,而是共用一份。 - 如果网络无法连接或速度较慢、Payload的提取会比较慢,影响VA的效率
- 可以通过UnrealVirtualizationTool来批量虚拟化和逆转换
加载虚拟化数据
从DDC获取
当加载一个已经虚拟化的资产时,会优先从DDC中获取:
在UE5中,本地DDC的路径为
%LOCALAPPDATA%l/UnrealEngine/Common/Zen/Data
,如果要模拟本地无DDC缓存的情况,可以把该目录删掉。
若从DDC中能够获取到,则不会请求P4上的payload。
从p4获取
如果从DDC中无法获取到资产的缓存,就会尝试从P4上获取:
获取数据后就与正常的资产访问没区别了。
无网络访问
当开启了资产虚拟化,并且在DDC中没有缓存,如果网络出现故障,无法访问P4,在打开资源时会报如下错误:
要么重试请求,要么直接退出引擎。
被动加载的资产也是这个逻辑(比如打开场景->加载模型->加载贴图),如果贴图的虚拟化数据无法加载,也会导致地图无法打开:
这就意味着,如果网络状态不佳,Virtual Assets处于完全不可用的状态。
引擎内在Core.VirtualizationModule
中支持通过UseLegacyErrorHandling
来忽略弹窗,不退出编辑器,但会触发断言,贴图为非致命断言,StaticMesh为致命断言。
虽然可以在打开贴图时不报错,但贴图尺寸显示为0x0大小:
注:无网络的问题,笔者在层UDN上也询问了Epic官方,目前官方并无断网时fallback临时数据的开发计划,而是建议网络良好时全量下载payload数据。
错误处理
p4 server配置
如果在引擎内check-in时有如下报错:
1 | SourceControl: Error: CommandMessage Command: CreateWorkspace, Error: Error in client specification. |
则是因为Virtual Assets同样需要p4 server做配置支持,开启下面两项配置:
- partitioned
- 虚拟化存储目录(DepotRoot)需要设置为
client.readonly.dir
然后就能够正常的check-in时虚拟化并提交了:
相关资料
官方文档
总结
总的来说,UE5的Virtual Assets是一个可以大幅降低拉取资产量的资源管理方式,在网络畅通的情况下资产访问体验与原生差异不大。
Virtual Assets最好要与共享DDC结合,虽然他们两个不强关联,但是从体验上来说还是必要的。只要对应资产在DDC缓存了一次,就不会每个用户都去P4 Server拉取文件了,而是优先从DDC访问,能够极大程度环节p4 Server的下载压力。
并且虚拟化也能带来资产去重的效果,比如同一张贴图被重复导入了两次,则实际只有一份Payload,可以避免资产的存储冗余(但实际资产的uasset
还是两个,不过它比较小)。
另外,Virtual Asset只能与P4结合,对其他版本控制系统支持不够,在断网状态下处于不可用状态,需要根据项目实际情况进行启用评估。
我的建议:如果你的UE5新项目使用P4作为版本控制,内网稳定性较好并能够部署SharedDDC,可以启用虚拟资产。