UE5虚拟资产的可用性分析

Availability Analysis of UE5 Virtual Assets

随着游戏规模和资产精度的提升,以及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
2
3
4
5
6
7
8
9
10
11
[Core.ContentVirtualization]
SystemName=Default

[Core.VirtualizationModule]
BackendGraph=VABackendGraph_Example

[VABackendGraph_Example]
PersistentStorageHierarchy=(Entry=SourceControlCache)
CacheStorageHierarchy=(Entry=DDCCache)
SourceControlCache=(Type=p4SourceControl, DepotRoot="...")
DDCCache=(Type=DDCBackend)

需要注意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
2
3
4
5
6
7
8
9
10
11
12
13
Usage:
Commands:
<ProjectFilePath> -Mode=Virtualize -Changelist=<number> -Submit [optional]
<ProjectFilePath> -Mode=Virtualize -Path=<string>
LogVirtualizationTool: Display:
<ProjectFilePath> -Mode=Rehydrate -Package=<string>
<ProjectFilePath> -Mode=Rehydrate -PackageDir=<string>
<ProjectFilePath> -Mode=Rehydrate -Changelist=<number>
Legacy Commands:
-Mode=Changelist -ClientSpecName=<name> [optional] -Changelist=<number> -nosubmit [optional]
-Mode=PackageList -Path=<string>
Global Options:
-MinimalLogging (demote log messages with 'display' verbosity to 'log' verbosity except those using the LogVirtualizationTool category)

仅虚拟化部分资产

禁用资产类型

如果想要某种类型不参与虚拟化,引擎提供了配置支持。

DefaultEngine.ini中控制某种类型的资产不参与虚拟化:

Developer/Virtualization/Private/VirtualizationManager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
TArray<FString> DisabledAssetTypesFromIni;
if (ConfigFile.GetArray(LegacyConfigSection, TEXT("DisabledAsset"), DisabledAssetTypesFromIni) > 0 ||
ConfigFile.GetArray(ConfigSection, TEXT("DisabledAsset"), DisabledAssetTypesFromIni) > 0)
{
UE_LOG(LogVirtualization, Display, TEXT("\tVirtualization is disabled for payloads of the following assets:"));
DisabledAssetTypes.Reserve(DisabledAssetTypesFromIni.Num());
for(const FString& AssetType : DisabledAssetTypesFromIni)
{
UE_LOG(LogVirtualization, Display, TEXT("\t\t%s"), *AssetType);
DisabledAssetTypes.Add(FName(AssetType));
}
}

可以在Core.ContentVirtualizationCore.VirtualizationModule的Section下添加:

1
2
[Core.VirtualizationModule]
+DisabledAsset="Texture2D"

在启动时就会有如下输出:

1
2
LogVirtualization: Display: 	Virtualization is disabled for payloads of the following assets:
LogVirtualization: Display: Texture2D

在引擎内提交贴图时就不会自动进行虚拟化了。

但引擎目前(UE5.6.0)仅提供了DiabledAsset的配置,相当于黑名单。并没有提供类似白名单的选项,这个可以自己改引擎代码扩展。

禁用路径/资产

如果想要某些路径/资产控制是否虚拟化,可以把下面的配置放入DefaultEngine.ini中:

DefaultEngine.ini
1
2
3
[/Script/Virtualization.VirtualizationFilterSettings]  
+ExcludePackagePaths="/Game/Meshs"
+IncludePackagePaths="/Game/Textures"

这两项配置会在FVirtualizationManager::ShouldVirtualizePackage中使用:

注意事项

  1. 不能把Saved/VASubmission目录标记为p4ignore,如果加了Saved/也会把它过滤掉。
  2. 资产虚拟化之后,如果删除引擎内的资产,对应的虚拟化文件并不会被删除,是一直累加的。
  3. 虚拟化文件会自动去重,比如同一张图片的重复导入,不会生成多份upayload,而是共用一份。
  4. 如果网络无法连接或速度较慢、Payload的提取会比较慢,影响VA的效率
  5. 可以通过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
2
3
SourceControl: Error: CommandMessage Command: CreateWorkspace, Error: Error in client specification.  
'partitioned' client type has not been configured for this server.
Storage location 'client.readonly.dir' needs to be set by the administrator.

则是因为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,可以启用虚拟资产。

全文完,若有不足之处请评论指正。

微信扫描二维码,关注我的公众号。

本文标题:UE5虚拟资产的可用性分析
文章作者:查利鹏
发布时间:2025/09/26 17:34
本文字数:3k 字
原始链接:https://imzlp.com/posts/6069/
许可协议: CC BY-NC-SA 4.0
文章禁止全文转载,摘要转发请保留原文链接及作者信息,谢谢!
您的捐赠将鼓励我继续创作!