Fork me on GitHub

UE5 增量 Cook

UE5 增量 Cook

UE 版本 5.5.4

  • 关键
    • -iterativecooking

添加了之后的 log 如下

image-20250815202658904

这部分 log 比较重要

cs 中

image-20250818120051662

image-20250818120010488

-iterativecooking 等同于 -iterate

数据结构

1. FAssetPackageData

image-20250815213552276

image-20250815213619730

简单来说根据 GetPackageSavedHash() 判断包是否修改

根据 DiskSize 判断包修改的状态

  • 状态

    image-20250815213816678

  • 包类型分类:

    • 包分为 已 Cook未 Cook占位包 (NeverCookPlaceholder)和 脚本包 Script
    • 每种类型有 Identical 相同Modified 修改Removed 删除 状态。

2. ICookedPackageWriter

2. FCookSavePackageContext 烘焙保存包上下文

对一个给定的平台,传递给 SavePackage 的上下文数据。

image-20250818142743787

实际上就是存储了

函数逻辑

1. LoadBeginCookIterativeFlags

image-20250815202936321

image-20250815202855644

image-20250815202805085

这里的 CookWorkerRequests 是在 COTFS 的 Intialize 函数中初始化的

image-20250815204603008

这个函数的目的也只是遍历传进来的 FBeginCookContext ,设置其中的 PlatformContext 的 相关 flag,如不是 FullBuild,允许 IterativeResults 等,以及

bPopulateMemoryResultsFromDiskResults 是否允许从磁盘的结果填充记忆结果。

2. PopulateCookedPackages

StartCookByTheBookLoadBeginCookIterativeFlags 结束之后,走到 BeginCookSandbox

image-20250815205226180

这里会根据 LoadBeginCookIterativeFlags 中指定的 bPopulateMemoryResultsFromDiskResults 执行后续逻辑,添加目标平台,执行 PopulateCookedPackages

image-20250815205342465

这是进行差异化判断的核心函数

image-20250815204801832

image-20250815214139990

ComputePackageDifferences 是另一个核心函数

3. ComputePackageDifferences

这个函数很长,但是逻辑是比较清晰的

前面先调用

image-20250815214717880

根据 FAssetPackageData 中的 Hash 值直接判断是否发生变化

image-20250815214912756

如果没有变化,就根据 DiskSize 进行状态的变更,添加到 OutDifference.Packages 数组中,记录状态

这里用 Mermaid 画一个流程图

graph TD A[Start ComputePackageDifferences] --> B[Initialize: Reserve OutDifference.Packages] B --> C[Loop through Current State's Packages] C --> D{Is Package in Previous State?} D -->|No| E[Skip: New Package, No Action] D -->|Yes| F[Check if Package is Unchanged] F -->|Yes| G{Is DiskSize < 0?} G -->|Yes| H{Is NeverCookPlaceholder?} H -->|Yes| I[Add to Packages: IdenticalNeverCookPlaceholder] H -->|No| J[Add to Packages: IdenticalUncooked] G -->|No| K{Is Script Package?} K -->|Yes| L[Add to Packages: IdenticalScript] K -->|No| M[Add to Packages: IdenticalCooked] F -->|No| N{Is DiskSize < 0?} N -->|Yes| O{Is NeverCookPlaceholder?} O -->|Yes| P[Add to Packages: ModifiedNeverCookPlaceholder] O -->|No| Q[Add to Packages: ModifiedUncooked] N -->|No| R{Is Script Package?} R -->|Yes| S[Add to Packages: ModifiedScript] R -->|No| T[Add to Packages: ModifiedCooked] E --> U[Loop through Previous State's Packages] U --> V{Is Package in Current State?} V -->|Yes| W[No Action: Already Processed] V -->|No| X{Is Generated Package?} X -->|Yes| Y{Is Generator in Current State?} Y -->|No| Z[Add to Packages: RemovedCooked] Y -->|Yes| AA[Add to GeneratorPackages] X -->|No| AB{Is DiskSize < 0?} AB -->|Yes| AC{Is NeverCookPlaceholder?} AC -->|Yes| AD[Add to Packages: RemovedNeverCookPlaceholder] AC -->|No| AE[Add to Packages: RemovedUncooked] AB -->|No| AF{Is Script Package?} AF -->|Yes| AG[Add to Packages: RemovedScript] AF -->|No| AH[Add to Packages: RemovedCooked] W --> AI[Loop through GeneratorPackages] AI --> AJ{Is Generator RemovedCooked?} AJ -->|Yes| AK[Mark All Generated Packages as RemovedCooked] AJ -->|No| AL[Keep GeneratorPackages Entry] AK --> AM{Check Options.bRecurseModifications?} AL --> AM AM -->|No| AN[End] AM -->|Yes| AO[Collect Modified Packages to VisitStack] AO --> AP[Loop through VisitStack] AP --> AQ{Stack Empty?} AQ -->|Yes| AN AQ -->|No| AR[Pop Package from VisitStack] AR --> AS[Get Referencers: Hard and Build Dependencies] AS --> AT[Loop through Referencers] AT --> AU{Is External Actor Package?} AU -->|Yes| AV{Refers to Modified Package's Map?} AV -->|Yes| AW[Skip Referencer] AV -->|No| AX{Already Visited?} AU -->|No| AX AX -->|Yes| AY[Skip Referencer] AX -->|No| AZ{Is Referencer in Packages?} AZ -->|No| BA[Skip Referencer] AZ -->|Yes| BB[Convert Identical to Modified] BB --> BC[Add Referencer to VisitStack] BC --> AT AW --> AT AY --> AT BA --> AT
posted @ 2025-09-19 13:20  icewalnut  阅读(72)  评论(0)    收藏  举报