中EN
概念页

烘焙、打包与 Zen 加载器

Cooking, Packaging & Zen Loader

更新于 2026-10-12 约 10 分钟UE5Cook打包IoStoreZen LoaderPak

打包是一组构建操作:编译 (Build) → 烘焙 (Cook,把资产转成目标平台格式) → 暂存 (Stage) → 打包 (Package) → 可选的部署 (Deploy)。UE5 的运行时加载器 Zen Loader 会在暂存阶段离线算好包与对象的依赖图,并把数据装进 .utoc/.ucas 容器(IoStore),由 I/O 分发器以很低的 CPU 开销定位数据块;.pak 只用于不常访问的零散文件。

打包流水线

flowchart LR
  B["Build<br/>编译代码、插件"] --> C["Cook<br/>资产转平台格式"] --> S["Stage<br/>复制到暂存目录<br/>并离线计算依赖"] --> K["Package<br/>打成可分发文件<br/>.pak / .utoc / .ucas"] --> D["Deploy(可选)<br/>推到目标设备"]

官方:打包把项目内容编译成能在目标平台运行的格式,本身是一个构建操作;Build、Cook、Stage 都是参与打包的构建操作。Build 为目标平台编译代码、插件和二进制;Cook 把几何体、材质、纹理、蓝图、音频等资产保存成目标平台能运行的格式;Stage 把编译好的代码和烘焙后的内容复制到开发目录之外的暂存目录;Package 把它们打成可分发的文件(Windows 上是可执行文件加一个装有 .pak 的文件夹);最后可选 Deploy。为主机开发和打包需要源码版引擎,不能用 Launcher 预编译版;Linux、移动端、XR 等平台可能还需要额外的 SDK。(Packaging Your Project)

为什么要烘焙

引擎内部用 PNG(纹理)、WAV(音频)等格式存资产,但各平台可能使用专有格式、不支持这些格式,或者有更省内存、性能更好的格式,因此要转换,这个过程叫烘焙 (cooking)。(Cooking Content in Unreal Engine)纹理烘焙成平台压缩格式就是 纹理压缩 的落地。

Cook 命令行参数作用
-iterate只烘焙过期的内容;不加时会删掉沙盒目录、全部重新烘焙
-cookonthefly以服务器模式启动,等游戏连上后按需提供烘焙数据
-UnVersioned保存不带版本号的包
-Compressed压缩烘焙后的包
-cookall烘焙全部内容

(Cooking Content in Unreal Engine)迭代开发时用 -iterate 可以大幅缩短烘焙时间;正式出包时更稳妥的做法是全量重新烘焙(这一点是工程经验归纳)。

Zen Loader 与 IoStore 容器

  • Zen Loader 是 UE5 新的运行时加载器。它在暂存阶段离线计算经过优化的包和对象依赖图,以降低 CPU 开销。它不再把所有资产打进 .pak,而是把包数据、bulk data 和着色器数据放进一组 .utoc / .ucas 容器文件:.utoc 描述容器(块大小与偏移、压缩格式、是否加密),.ucas 存实际数据;.pak 只用于不常访问的零散文件。挂载 Pak 时,对应的容器也会一并挂载。(Zen Loader in Unreal Engine)
  • 容器绕开了文件系统抽象,由新的 I/O 抽象层 I/O dispatcher 以最小的 CPU 开销找到数据块。UAT 在暂存时默认生成容器,运行时检测到容器就会启用 Zen Loader。(Zen Loader in Unreal Engine)
  • 坑:用 Zen Loader 时,初次序列化完成后 BulkData 不能再加载内联数据,也就是说数据一旦卸载就无法再取回。UnrealPak 可以检查容器:-list、-diff、-extract,IoStore 下还有 -describe(查看依赖、包、导入导出)。(Zen Loader in Unreal Engine)
  • 依赖图离线算好之后,运行时的异步加载(见 资产管理与异步加载)就不必临时解析依赖,这是 Zen Loader 省 CPU 的来源。

包结构:导入表与导出表

官方没有讲 .uasset 文件布局的概述页(FPackageFileSummary 的 API 页返回 403),以下只依据 5.8 API 参考中的链接器 (Linker) 类型说明。(FLinkerTables / FPackageIndex / FObjectExport (API))

表内容
ExportMap (FObjectExport)包内定义、可以被其他包引用的对象
ImportMap (FObjectImport)本包引用的外部对象
DependsMap每个导出各自的依赖列表
SoftPackageReferenceList本包软引用的包

包内的对象引用都用 FPackageIndex 编码:

Index>0⇒ExportMap[Index−1],Index<0⇒ImportMap[−Index−1],Index=0⇒null\text{Index}>0 \Rightarrow \text{ExportMap}[\text{Index}-1],\qquad \text{Index}<0 \Rightarrow \text{ImportMap}[-\text{Index}-1],\qquad \text{Index}=0 \Rightarrow \text{null}

每条导出记录里有 ClassIndex、SuperIndex、TemplateIndex(也是 FPackageIndex)、对象标志,以及 SerialOffset/SerialSize:这是该对象数据在文件读取存档 (archive) 中的起始位置和字节数。ScriptSerializationStart/EndOffset 标出其中使用带标签属性序列化 (Tagged Property Serialization) 的那一段。bNotForClient/bNotForServer 控制客户端或服务器是否加载这个导出。(FLinkerTables / FPackageIndex / FObjectExport (API))

文件头 FPackageFileSummary(依据 UE 5.6 API;5.8 版本页返回 403):官方称之为包文件的「目录 (table of contents)」,存放在文件开头。(FPackageFileSummary)

字段组字段(官方说明)
魔数Tag:与 PACKAGE_FILE_TAG 比较,确认这是 Unreal 包
版本FileVersionUE(UE 文件版本)、FileVersionLicenseeUE(授权方版本)、CustomVersionContainer(按各组件唯一标签记录的自定义版本)、SavedByEngineVersion、CompatibleWithEngineVersion;bUnversioned 表示保存时不带版本号
表的位置NameCount/NameOffset、ImportCount/ImportOffset、ExportCount/ExportOffset、DependsOffset、SoftPackageReferencesCount/Offset、SearchableNamesOffset、PreloadDependencyCount/Offset
其他数据TotalHeaderSize(创建 FLinkerLoad 需要读入的全部信息大小)、BulkDataStartOffset、PayloadTocOffset、ThumbnailTableOffset、AssetRegistryDataOffset、GatherableTextDataCount/Offset(可收集文本,供本地化使用)、WorldTileInfoDataOffset
标识PackageName、PersistentGuid、PackageFlags、Generations(历史版本信息)、SavedHash(保存时包字节的哈希)、ChunkIDs(流式安装分块)

版本检查函数:IsFileVersionTooOld()/IsFileVersionTooNew() 判断包版本是否低于最低支持版本或高于当前进程支持的版本;IsFileVersionValid() 在包未带版本号且当前进程不支持时返回 false。(FPackageFileSummary)也就是说,加载器先读文件头,用 Offset 定位各张表,再按导出表中的 SerialOffset 读取对象数据(读取顺序是根据字段含义归纳的)。PACKAGE_FILE_TAG 的数值在官方 API 页(5.3–5.8 各版本都只返回目录)中查不到。非官方来源(第三方博客引用的引擎源码 Core/Public/UObject/ObjectVersion.h)给出的定义是 #define PACKAGE_FILE_TAG 0x9E2A83C1,字节序相反时为 PACKAGE_FILE_TAG_SWAPPED 0xC1832A9E,即 .uasset 文件的前 4 个字节;引擎加载时先检查这个值,再反序列化 PackageFileSummary。(Unreal Resource Management: A raw uasset Encryption Scheme,非官方,未经 Epic 文档核实)

GEA 的视角:何时做平台相关处理(卷 II 16.4.2.1)

GEA 把资产处理分为"导出到平台无关中间格式"和"处理成平台优化格式"两步,并比较第二步的时机:Source、Quake 在运行前烘焙关卡时做;Halo 在首次加载进引擎时做并缓存结果;而对 UnrealEd,GEA 写的是"在资产首次导入编辑器时"完成,好处是关卡迭代快,代价是修改源资产更麻烦。

分歧:本页依据 UE 5.8 文档,资产在引擎内部以 PNG、WAV 等格式保存,转换为平台格式发生在 Cook 阶段。两者并列记录;GEA 的描述可能针对较早的 UnrealEd,书中没有说明版本。

对比表与世界编辑器的其余功能见 数据驱动与游戏世界编辑器。

  1. Cooking Content in Unreal Engine UE 5.8 文档
  2. Packaging Your Project UE 5.8 文档
  3. Zen Loader in Unreal Engine UE 5.8 文档
  4. FLinkerTables / FPackageIndex / FObjectExport (API) UE 5.8 API 参考(链接器表)
  5. FPackageFileSummary UE 5.6 API(FPackageFileSummary)
  6. Unreal Resource Management: A raw uasset Encryption Scheme 【非官方】第三方博客引用源码
  7. Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
  8. Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 16 章 16.4.2.1 节

相关页面

游戏开发 · UE5资产管理与异步加载Asset Management & Async LoadingUE 资产默认按引用自动加载:硬引用 (Hard Reference) 会让被引用资产随引用者一起加载,不加控制就可能在启动时加载全部内容。软引用 (Soft Reference,TSoftObjectPtr/FSoftObjectPath) 只存路径,配合流式管理器 (Streamable Manager) 异步按需加载;资产管理器 (Asset Manager) 进一步把内容划分为主资产 (Primary Asset) 和次资产 (Secondary Asset),用资产包 (Asset Bundle) 管理加载、卸载、烘焙分块与内存审计。游戏开发 · UE5模块、插件与构建系统Modules, Plugins & Build SystemUE 的代码由模块 (Module) 组成:每个模块是一个独立编译单元,用 [模块名].Build.cs 声明依赖。插件 (Plugin) 是可按项目启用/禁用的代码与内容集合,用 .uplugin 描述,可包含多个模块。虚幻构建工具 (UnrealBuildTool, UBT) 根据 .Target.cs 和 .Build.cs(而不是 IDE 的 .sln)编译,默认把模块编成 DLL 由一个可执行文件加载,也可整体链接成单体 (Monolithic) 可执行文件。游戏开发 · UE5专用服务器Dedicated ServerUE 多人游戏采用客户端-服务器模型。监听服务器 (listen server) 由某个玩家的客户端兼任服务器;专用服务器 (dedicated server) 无头运行,不渲染画面,也没有本地玩家。专用服务器体积更小、房主没有不公平优势、能专注于玩法逻辑,适合大规模或竞技游戏。构建专用服务器需要源码版引擎和支持客户端-服务器的 C++ 项目,并要有 <ProjectServer.Target.cs。游戏开发 · UE5配置文件系统Configuration FilesUE 的 .ini 配置按类别(Engine、Game、Input……)分层加载:从引擎 Base 文件到项目 Default 文件,再到平台文件和用户文件,后加载的同名键覆盖先加载的。数组可以用 +、-、! 等运算符跨层增删。UCLASS(config=X) 加上 UPROPERTY(Config) 可以让类的默认值从 ini 自动读取;命令行 -ini: 可以临时覆盖。图形学纹理压缩Texture Compression固定码率纹理压缩由 GPU 实时解码:减少显存占用、增大有效缓存、降低访问带宽,也能在同样内存下用更大纹理。BC (DXTC) 系列是桌面标准,ETC/EAC、PVRTC、ASTC 用于移动平台。它们都是有损的,压缩慢、解压快;法线贴图需要专门处理。游戏开发 · UE5自动化测试Automation TestingUE 的自动化系统 (Automation System) 构建在功能测试框架之上,支持单元测试、功能测试、内容压力测试和截图对比,并借助 Unreal Message Bus 提高稳定性。测试按用途分为 Unit、Feature、Smoke(承诺 1 秒内完成)、Content Stress 和 Screenshot Comparison。它依赖引擎系统运行,所以不适合纯粹的单元测试;这种情况用 Low-Level Tests。跨进程的整局会话测试用 Gauntlet。游戏开发 · UE5本地化LocalizationUE 的本地化以 FText 类型为中心,国际化(数字、日期、复数规则、文化回退)依赖 ICU 库。可本地化的文本由命名空间、键、源字符串三部分标识;本地化管线按目标 (Localization Target) 依次收集 (Gather) 到 manifest、翻译进各文化的 archive(通常经 PO 文件导出导入)、编译成运行时加载的 .locres。Localization Dashboard 是管理这条管线的推荐工具。游戏开发 · UE5像素流送Pixel Streaming像素流送 (Pixel Streaming) 让 UE 应用运行在桌面 PC 或云服务器上,把渲染好的画面和音频编码成媒体流,通过 WebRTC 点对点发送到浏览器和移动设备;用户可以在网页里用键盘、鼠标、触摸、手柄操作应用。系统由引擎内的 Pixel Streaming 插件和一个信令与 Web 服务器 (Signalling and Web Server) 组成,跨网络连接时需要 STUN/TURN。游戏开发资产管线与工具链Asset Conditioning Pipeline & Tools游戏引擎的输入数据来自美术使用的数字内容创作 (DCC) 工具,但 DCC 格式几乎从不直接用于游戏,必须经过资产调理管线 (Asset Conditioning Pipeline, ACP) 导出、处理并按平台打包。围绕它还有世界编辑器、记录资产元数据的资源数据库,以及几种工具架构(独立工具、与引擎共享底层、编辑器内嵌于引擎、Web 界面),各有取舍。游戏开发引擎文件系统与异步文件读写Engine File System & Asynchronous File IO资源管理器大量依赖文件系统。引擎通常把操作系统的文件 API 包装成自己的 API:一是跨平台、屏蔽硬件差异;二是操作系统缺少引擎需要的功能(如流式加载),主机还要统一访问记忆棒、硬盘、蓝光盘、网络文件系统等介质。引擎文件系统 API 通常涵盖:文件名与路径操作、打开/关闭/读写文件、扫描目录、处理异步 I/O 请求(流式加载)。游戏开发数据驱动与游戏世界编辑器Data-Driven Engines & Game World Editors当游戏行为可以部分或全部由美术和策划提供的数据控制,而不只由程序员写的代码控制时,引擎就是数据驱动的。它能提高团队效率、缩短迭代时间,但工具、健壮的运行时和预览手段都要花大量成本,过度设计反而降低生产力,所以要权衡并坚持 KISS。玩法领域里对应 DCC 工具的是游戏世界编辑器:创建世界块并放入静态和动态元素、设定对象初始状态和行为。GEA 列出了它的典型功能,并比较了不同引擎在何时做平台相关优化上的取舍(GEA4 卷 II 16.3–16.4)。游戏开发资源管理器Resource Manager游戏由网格、材质、纹理、着色器、动画、音频、关卡布局、碰撞与物理参数等大量资源(也叫资产、媒体)构成。内存有限,所以引擎要保证每个资源在内存中只有一份(五个网格共用一张纹理时只载入一份)。每个引擎都有某种资源管理器:有的是统一集中的子系统,有的散布在多年间由不同人写的各个子系统中,但职责和要解决的问题是一样的。本页讲运行时部分:职责、文件组织与归档、文件格式、资源 GUID、资源注册表、生命周期(引用计数)和资源的内存管理;交叉引用与加载后初始化见 资源交叉引用与加载后初始化,离线工具链见 资产管线与工具链。

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原