UE4 Cook流程中IdenticalUncookedPackages的含义,以及一种“资源未打包”情形的解释

背景

某次调整入包地图时,发现某张地图没有成功打包。于是调查并做此记录。

操作过程:

第一次构建时,配置DefaultGame.ini如下:

+MapsToCook=(FilePath="M的路径")

第二次构建时,配置DefaultGame.ini如下:

; (注释掉的意思)+MapsToCook=(FilePath="M的路径")

+DirectoriesToNeverCookWildcard=M的路径

第三次构建时,配置DefaultGame.ini如下:

+MapsToCook=(FilePath="M的路径")

; +DirectoriesToNeverCookWildcard=M的路径

表现:第一次构建时,包体里有M;第二次构建时,包体里没有M;第三次构建时,包体里依然没有M,预期有M,因此属于错误情况。

接下来我们看为何M在第三次时没能成功Cook。

结论先行

1、根据 《IgnoreIniSettingsOutOfDate开关的介绍》 ,由于我所在的项目里,打开了 IgnoreIniSettingsOutOfDate ,因此不会在 "项目的打包配置(尤其是Cook设置)发生重大变更",走UE4自带的 "清理整个 Saved目录" 的逻辑。

2、DirectoriesToNeverCookWildcard 的反注释,属于"重大变更" ,因此需要清理Saved目录。

3、解决方法:

● 以后都关闭 IgnoreIniSettingsOutOfDate ,遇到这类问题就不用担心出问题。

● 保持 IgnoreIniSettingsOutOfDate ,当 DirectoriesToNeverCookWildcard 反注释时,主动清理 Saved目录(搞清楚所有原理后,我们能更加精确地得知,只需要清理 Saved/Cooked 即可)。

接下来我们看看原理细节。

IdenticalUncookedPackages

在真正开始Cook前,UE4会根据上一次的 原始资源状态(记录在 D:\我的工程\Saved\Cooked\平台名LinuxServer\我的工程名\Metadata\DevelopmentAssetRegistry.bin )(代码见 PreviousPackageData),和当前的资源状态,做比较,其中一种情形如下,当原始资源哈希没有变化,且曾经没有真正产出到 Saved/Cooked 目录中 (PreviousPackageData->DiskSize < 0)时,该资源归属于 IdenticalUncookedPackages 。

复制代码
// 位于void FAssetRegistryGenerator::ComputePackageDifferences(......)   EngineSource\Engine\Source\Editor\UnrealEd\Private\Commandlets\AssetRegistryGenerator.cpp
......
else if (CurrentPackageData->PackageGuid == PreviousPackageData->PackageGuid)
{
	if (PreviousPackageData->DiskSize < 0)
	{
		IdenticalUncookedPackages.Add(PackageName);
	}
	else
	{
		IdenticalCookedPackages.Add(PackageName);		
	}
}
......

而从下面的代码可以看出IdenticalUncookedPackages 的含义------此资源会直接跳过cook,直接加入到 CookedPackages队列(已完成)、KeptPackages队列(未变化的资源队列 | 增量跳过队列)中,且++NumMarkedFailedSaveKept 也预示着,这个资源此次未能保存成功。

直白来说:"一旦因某种合理的原因没有Cook该资源",且Cook全流程完成了,那么后续构建遇到此资源,也会直接跳过,不会考虑Cook该资源。直到此原始资源MD5发生变更。

复制代码
// 位于 void UCookOnTheFlyServer::PopulateCookedPackagesFromDisk(......) EngineSource\Engine\Source\Editor\UnrealEd\Private\CookOnTheFlyServer.cpp

		// Register identical uncooked packages from previous run
		for (FName UncookedPackage : IdenticalUncookedPackages) // 直接认为 kept(也就是不用cook,直接放入到 cooked中)
		{
			const FName UncookedFilename = PackageNameCache->GetCachedStandardPackageFileFName(UncookedPackage);

			TArray<FName> PlatformNames;
			PlatformNames.Add(PlatformFName);

			ensure(PackageTracker->CookedPackages.Exists(UncookedFilename, PlatformNames, false) == false);

			PackageTracker->CookedPackages.Add(FFilePlatformCookedPackage(UncookedFilename, MoveTemp(PlatformNames)));
			KeptPackages.Add(UncookedPackage);
			++NumMarkedFailedSaveKept;
		}

代入到背景case中则是:

● "某种合理的原因"------背景介绍里第二次构建的配置,添加了 DirectoriesToNeverCookWildcard。

● "Cook全流程完成了"------背景介绍里第二次构建是成功的构建,并不属于异常。

● "后续构建"------第三次构建。

因此解决方法是删除 Saved/Cooked ,目的是让所有Cooked产物都删除掉,且让 PreviousPackageData 也删除掉(失效掉),因为PreviousPackageData 即 D:\我的工程\Saved\Cooked\平台名LinuxServer\我的工程名\Metadata\DevelopmentAssetRegistry.bin 也在 Saved/Cooked 中。

最佳实践

当你的工程很大,打开了 IgnoreIniSettingsOutOfDate 时,并且修改了 "进包配置",例如调整了 DirectoriesToNeverCookWildcard,那么需要删除掉 Saved/Cooked 。这个过程最好是自动化。

相关推荐
每天回答3个问题13 小时前
Lua Table(表)
开发语言·ue4·lua·虚幻引擎
每天回答3个问题7 天前
Lua数组
ue4·lua·虚幻引擎
每天回答3个问题7 天前
Lua 字符串
ue4·lua
道法自然040215 天前
[CARLA系列--05]如何在Carla中去调用传感器模型--Radar篇
人工智能·自动驾驶·ue4
Kin__Zhang1 个月前
随手记录 UE4/CARLA 仿真器 segmentation fault
android·java·ue4
小江村儿的文杰1 个月前
UE4在MacOS上将Commit.gitdeps.xml设为Git LFS文件的潜在弊端
xml·ue4
李岱诚1 个月前
epic商城下载,ue4报错处理
游戏引擎·ue4
爆米花煮鸡蛋1 个月前
UE4.27生成sln时失败:Missing .../DotNET/UnrealBuildTool/UnrealBuildTool/UnrealBuildTool.exe after build
ue4
海中有金1 个月前
UE4 内存池浅谈[3]——3代内存池对比总观
ue4·图形渲染