Cook 与打包流程

自动关联目录:Cook 与打包流程

Cook 是"把编辑器里的资产转换成目标平台能直接用的格式"这一步。贴图转成平台压缩格式、Shader 编译成目标 API 的字节码、蓝图字节码化——都在这里发生。

一句话定位:打包 = Cook + 分 Chunk + 打进容器。而"编辑器里好好的,打包后不行",八成是 Cook 阶段的引用链和你以为的不一样。

三个阶段

1. Cook      资产按平台转换,产出 Cooked 资产(Saved/Cooked/<Platform>/)
2. Stage     按 Chunk 规则把 Cooked 资产分堆,复制到 Staged 目录
3. Package   把每堆打进 .pak / .utoc+.ucas,签名加密,产出可分发包

Cook 做了什么

资产Cook 时发生
Texture压缩成平台格式(BC/ASTC/ETC2),生成 mip
StaticMesh生成平台渲染数据、NaN 剔除、距离场
Material编译 shader permutation,生成 PSO 缓存
Blueprint字节码编译、依赖解析
Sound重编码(ogg/opus 等)
所有资产序列化成平台字节序

Cook 只处理"被引用的资产"。没有引用链、也没有 PrimaryAsset 规则的资产不会被 Cook——这是"打包后资源丢失"的第一原因。

引用链怎么决定要不要打进包

启动关卡 / PrimaryAsset / 被扫描的目录
        │  引用链
        ▼
所有被引用到的资产 → 进包
孤立资产(无人引用) → 不进包

编辑器里能加载不等于会被打包:编辑器可以直接读 .uasset 源文件,打包后只读 Cooked 内容。所以"编辑器能跑、打包后找不到"是必然会出现的一类问题。

DDC(Derived Data Cache)

DDC 缓存 Cook 的中间产物,避免每次全量重 Cook。

类型位置说明
Local DDC本机 Saved/DerivedDataCache默认
Shared DDC网络共享目录团队共享,CI 上尤其重要
Cloud DDC云端分布式团队

配置在 DefaultEngine.ini:

[DerivedDataBackendGraph]
MinimumDaysToKeepFile=7
Root=(Type=KeyLength, Length=120, Inner=AsyncPut, Inner=HierarchicalCache, Inner=FileSystem, ...)
现象原因
每次打包都很慢DDC 没命中,或没配 Shared DDC
换台机器就要重新 Cook只有 Local DDC
CI 打包慢CI 机器上 DDC 是空的,应指向 Shared

Shader 编译占了 Cook 时间的大头,配好共享 DDC + 稳定的 shader 缓存能省下大量时间。

平台差异

平台注意
Windows / 主机包体大,IO 快,允许不压缩
Android需要 ASTC/ETC2,可能有 OBB 分包限制
iOS需要 ASTC/PVRTC,App Store 有包体与按需资源限制
移动端通用要开 bShareMaterialShaderCode、bSharedMaterialNativeLibraries

移动端最常见的包体问题:shader 库没共享、贴图压缩格式没按平台设、把编辑器资产(bIsEditorOnly=False 忘设)打进了包。

Chunk 与 Stage

Chunk 划分规则见 AssetManager。Stage 阶段做的事是:

Chunk 0 → WindowsNoEditor/Content/Paks/WindowsNoEditor-Windows.pak  (主包)
Chunk 1 → ...-Windows_P.pak  (patch/分包)
配置说明
bGenerateChunks是否生成 chunk(否则全部进主包)
bChunkForReferenceDepth按引用深度分块
PrimaryAssetLabel编辑器里给资产打 chunk 标签
ChunkDownloader 数据生成 BuildManifest-<Platform>.json,供按需下载

ChunkId 相同的资产会进同一个 pak;被多个 Chunk 引用的资产会被打进多个 pak(重复但不报错)。

常用命令

# Cook(命令行)
RunUAT.bat BuildCookRun -project=MyGame.uproject -platform=Android -clientconfig=Development -cook -stage -pak -archive

# 只 Cook
RunUAT.bat BuildCookRun -project=MyGame.uproject -platform=Windows -cook -skipstage -skiparchive

# 列出 pak 内容
UnrealPak.exe WindowsNoEditor.pak -List > paklist.txt
参数含义
-cook执行 Cook
-stage复制到 Stage 目录
-pak打成 pak
-archive归档到输出目录
-iterate增量打包(只处理改动)
-clean先清空再 Cook

增量打包(-iterate)能极大缩短出包时间,但偶尔会漏掉改动。发布版本应做一次 clean 全量。

包体分析

工具用途
SizeMap(编辑器)单个资产的依赖总大小,找"谁最大"最快
UnrealPak.exe -List精确列出每个 pak 里的资产
Asset Audit(编辑器)按类型统计、对比平台
stat size运行时统计

控制的优先级:

  1. 贴图(通常占一半以上)——降分辨率、改压缩、去无用 mip
  2. 音频——降采样、流式播放
  3. 网格——LOD、Nanite
  4. Shader——共享库、减少 permutation(见 Rendering)
  5. 重复资产——被多 Chunk 引用

常见坑

坑说明
资产没被打进去无引用链且无 PrimaryAsset 规则
编辑器能跑打包不行同上,或 bIsEditorOnly 没设
每次打包都全量 CookDDC 未共享
包体突然变大新增资产硬引用了大批依赖,用 SizeMap 查
重复打包资产被多个 Chunk 引用
移动端包体异常贴图压缩格式、shader 未共享
增量打包漏改动发布前跑一次 clean
Cook 卡在某资产通常是 shader 编译或过大的贴图,看日志定位
打进去了编辑器资产检查 bIsEditorOnly 与 Cook 目录配置