“Unknown Cook Failure” 是 Unreal Engine 打包时最让人抓狂的错误之一。

最重要的一点是:

Unknown Cook Failure 通常只是最终汇总,而不是真正根因。

真正的错误往往出现在更早的位置,有时甚至在最终失败之前几百、几千行。

不要从最后一条红色错误开始看

很多人排查 Packaging Log 时会从最底部往上看。

最下面经常只有 AutomationTool 退出、Cook Failed、Packaging Failed 或 ExitCode 25。

这些信息告诉你“失败了”,但通常没有告诉你“为什么失败”。

更有效的做法是继续向前找到第一条真正把构建从正常状态变成不可恢复状态的错误。

最常见的根因分类

损坏或无效资产

一个损坏的 Asset、失效引用、旧 Redirector,或者已经无法正确反序列化的资源,可能只会在 Cook 阶段暴露。

常见线索包括 Package 加载失败、Import 丢失、Serialization Error、无效 Object Reference,或者前面大量 Warning 最终演变成 Fatal。

Plugin 和 Module 问题

一个插件在 Editor 里可能完全正常,但目标平台 Cook 或 Link 时失败。

重点看 Module validation failure、缺失目标平台二进制、Plugin Descriptor 不兼容、Target Module 不存在,或者 Packaged Build 中误用了 Editor-only 代码。

Shader 编译失败

Shader 错误经常埋在巨大的 Cook Log 里。

最终仍然只显示 Unknown Cook Failure。

要找的是最早出现的 Shader Compile Error、Platform permutation failure 或 Generated shader code error。

SDK 和工具链不匹配

有时失败原因是机器使用了错误的 Compiler、SDK、Platform Tools、环境变量、签名工具或 Target Platform Package。

最重要的是先判断:

错误到底发生在 Cook 内容阶段,还是后面的 Build / Package 阶段。

Derived Data Cache 和旧中间产物

删除 Saved、Intermediate、DDC 是非常常见的排查方式,因为旧生成状态确实可能导致非常混乱的问题。

但它不应该成为所有 Cook Failure 的第一答案。

如果清缓存能解决,也应该继续理解究竟是什么状态失去一致性,否则问题可能反复回来。

更好的排查顺序

1. 标记最终失败点

先找到最终 Unknown Cook Failure 或 AutomationTool Exit。

2. 向前找第一条真正错误

不要停在二次错误。

继续向上,直到出现第一条明确指出 Asset、Plugin、Source File、Shader、SDK 组件或某个具体 Command 的错误。

3. 给根因分类

把第一条因果错误归入:

  • 资产/内容;
  • Plugin/Module;
  • Shader;
  • SDK/工具链;
  • 权限/路径;
  • 内存/资源;
  • 签名/平台;
  • DDC/生成状态。

4. 缩小复现范围

如果可能,只 Cook 出问题的 Map、目标平台或者一组 Content。

越小的复现,越容易从海量 Log 中排除噪声。

5. 一次只修改一个层面

不要同时清缓存、重装 SDK、关插件、移动工程和修改构建配置。

如果一次改五个变量,即使最后成功,也不知道真正修复了什么。

为什么日志越大,这个问题越严重

现代 Unreal 项目的 Packaging Log 可以非常大。

开发者真正需要的不是另一个文本搜索框。

更有价值的诊断工具应该能理解:

这条 Warning 是前面那个 Missing Asset 的下游结果;

或者:

后面 40 条 Shader Error,其实全部来自同一个 Generated Include 失败。

这本质上是一个“根因分析”问题,而不是关键词搜索问题。

Build Doctor 应该做什么

一个真正有用的自动分析器应该:

  1. 解析完整 Build/Cook Log;
  2. 识别不同阶段边界;
  3. 建立错误因果链;
  4. 合并重复二次错误;
  5. 对根因排序;
  6. 指到第一处真正可行动的资产、插件、源码或环境问题;
  7. 给出最小验证步骤;
  8. 条件允许时只重新执行受影响的那一部分。

例如:

最终错误:Unknown Cook Failure
最可能根因:某个武器资源无法加载依赖的主材质
第一条因果错误:第 4,281 行
被合并的二次错误:73 条
验证方法:修复依赖后只 Cook 受影响内容

这远比告诉开发者 ExitCode 25 有价值。

Ycode 的方向

Ycode 把构建和打包日志放进完整开发循环,而不是把它们当成被动文本文件。

目标是:

build → 发现失败 → 找根因 → 建议或应用修复 → 只重建受影响部分 → 验证

同样的方法不只适用于 Unreal Cook Failure,也适用于 C++ 编译、Shader 编译、iOS 签名、Android 打包、分布式构建和 CI 失败。

问题复杂时应该保存什么

当 Unknown Cook Failure 很难解释时,至少保留完整日志、精确 Engine Version、Target Platform、Build Configuration、最近的插件改动、最近的 Asset 移动或重命名、实际执行的 Command Line,以及同一个工程在另一台机器上是否能 Cook。

不要只截图最后五行。

因为最后五行通常恰恰是整个日志里最没价值的部分。

最实用的一条规则

当 Unreal 告诉你:

Unknown Cook Failure

可以直接在脑中翻译成:

真正有用的错误大概率在更前面。

找到第一条因果错误、完成分类,再验证最小修复路径。

这是把一个模糊打包失败变成可行动工程问题的最短路径。