UE4第二次构建时,引擎是否主动删除掉Saved/Cooked目录
背景
在UE4中,当我的项目不断变大,我希望剔除掉一些不需要进包的地图时,我发现从出大包,切到出小包(剔除部分地图)时,得到的小包依然很大(后文都称为【Bug 0】)。除非我清除 Saved目录,才能得到合理的小包。
为此我看了一些代码,得到下面的推理:
1、一个事实:在我的项目实践中,Saved/Cooked 我没删除,只是删除了 Saved/StagedBuilds 、Saved/Archive 。
2、 Saved/Cooked 是 Saved/StagedBuilds 的前身,且其中的Pak是全量拷贝的(见 EngineSource\Engine\Source\Programs\AutomationTool\Scripts\CopyBuildToStagingDirectory.Automation.cs )
3、结合Cook中 “deleting cooked package” 的日志,从打包逻辑里看,只有 AssetRegistry 感知到发生“增删改”时,才会 deleting cooked package ,否则那些pak将保留在 Saved/Cooked 中。
4、由于“修改Config 使某些地图资源 NeverToCook” 这种变化,并不在 3 的考虑中,因此 多余资源在Saved/Cooked 中依然存在,缺乏删除的契机。【Mark 0.1】
5、由于1和2,因此会进入到最终包中。
为了更好地认识这个问题,先介绍一下 IgnoreIniSettingsOutOfDate 这个开关。
IgnoreIniSettingsOutOfDate开关
概括:它考虑的是——“打包配置 是否失效了”,如果失效,则将整个 Saved 目录删除掉。
1、当这个开关为false时:
构建系统会严格检查INI配置文件的变更;如果检测到任何INI设置发生变化,会认为整个构建已过期;需要重新进行完整构建,无法使用增量构建优化。
2、是否失效取决于一个中间ini,这个中间ini如【示例2】所示,代码如【代码1】所示。
// 关键代码1
// 位于 EngineSource\Engine\Source\Editor\UnrealEd\Private\CookOnTheFlyServer.cppbool UCookOnTheFlyServer::IniSettingsOutOfDate(const ITargetPlatform* TargetPlatform) const
{// 尝试读取 Saved\Cooked\WindowsClient\MyPro\Metadata\CookedIniVersion.txt// 如果读取失败,或者是其内容发生了变更,那么返回true,表示“out of date”// 如果没有变更,返回 false,表示“配置没有 out of date”
}// 示例2
// 见 Saved\Cooked\WindowsClient\MyPro\Metadata\CookedIniVersion.txt
……
TextureFormat:BC6H_NVTT3:VersionNumber=0
TextureFormat:BC7_NVTT3:VersionNumber=0
ShaderFormat:PCD3D_SM5:VersionNumber=-1951170411
ShaderFormat:PCD3D_ES31:VersionNumber=8
ShaderFormat:PCD3D_ES2:VersionNumber=8
fastcook=
Release:9C54D522A8264FBE9421074661B482D0=30
Dev-ShaderResource:121AAB9F88712AFCA67BC90C383ABD29=1Windows.Game:/Script/PlatformConfigModifier.PlatformConfigSettings:FilesToNeverCookWildcardInMobile:0=*_HD.*
Windows.Game:/Script/PlatformConfigModifier.PlatformConfigSettings:FilesToNeverCookWildcardInMobile:1=*_HD_*……
顺带一说,这个ini由 bool UCookOnTheFlyServer::SaveCurrentIniSettings 填充。
3、这个开关会导致什么行为?值为true时,会导致无论如何都不会主动删除 Saved/Cooked ,这就是 【Mark 0.1】 所说的“缺乏删除Saved/Cooked 的契机” 的重要原因。
// 关键代码3
// 位于 EngineSource\Engine\Source\Editor\UnrealEd\Private\CookOnTheFlyServer.cppvoid UCookOnTheFlyServer::CleanSandbox(const bool bIterative)
{……if (bIterative == false) // 如果不传 -iterative ,即不增量Cook,非典型行为,和本文无关联。{ClearPlatformCookedData(FName(*Target->PlatformName())); // 也就是删除Saved/Cooked目录} else {if ( 配置文件out of date了 ){if (!IsCookFlagSet(ECookInitializationFlags::IgnoreIniSettingsOutOfDate)){ 删除 Saved/Cooked 目录 }else{ 打印【日志4】见后文 }}}……
}在【Bug 0】这个案例中,构建日志打印了【日志4】:
2025-10-23 16:20:42:691 : LogCook: Display: Inisettings were out of date for platform WindowsClient but we are going with it anyway because IgnoreIniSettingsOutOfDate is set
4、UE4 默认是关闭的——不忽略,也就是要考虑ini过期,当过期时,删Saved目录。
在我的项目中是被精心考虑打开了的——要忽略,也就是无视ini是否过期,无论如何,都不删Saved目录。
结论:本文前面的推论 1~5 正确。
5、中场问答:当不 ignore 时,且改Config时,UE4原生引擎会把Saved目录全删除掉吗?
不会的。仅仅是部分的配置项,具体见本文附件 CookedIniVersion.txt。
其它问答
1、在UE4中,不管是何种平台的发布包,都会包含 pak文件,是吗?
在UE4中,无论是针对Windows、Android、iOS还是其他平台的发布包,只要在打包时启用了相应的选项,最终生成的发布包都会包含.pak文件。
2、Archived/.../Paks目录中的PAK文件并非由Package阶段“重新以平台相关格式发布”。它实际上是 Archive阶段 从 StagedBuilds/.../Paks目录中原样复制过来的副本
待论证。
后记
1、最佳实际
当项目的打包配置(尤其是Cook设置)发生重大变更时,应清理整个 Saved目录。这是因为UE4的这套增量机制虽然提升了日常迭代的效率,但在处理配置逻辑的变更时不够智能。
