World Partition
自动关联目录:World Partition
官方依据:World Partition(UE 5.8 Documentation)。本页覆盖该页全部 23 个条目,并补官方未写的代价、限制成因与排查顺序。
1. 定位
World Partition 是自动的数据管理 + 基于距离的关卡流式系统,为大型世界提供完整方案。它把世界存在单个持久关卡里并切成网格单元(grid cells),按到流式源的距离自动加载/卸载。
一句话定位:它取代了"手工切子关卡 + 用 Level Streaming 拼装"的旧做法。旧做法的两个痛点是:多人共享文件冲突、以及无法在上下文中看到整个世界。
它与四个特性紧密配合:One File Per Actor、Data Layers、Level Instancing、HLOD。
2. 启用方式(三种)
| 方式 | 说明 |
|---|---|
| 用 Games 分类的模板新建项目 | 许多模板默认启用 WP |
| 用 Open World 模板新建关卡 | WP + OFPA + Data Layers + HLOD 全部默认开启 |
| 转换现有关卡 | Tools > Convert Level,或用 WorldPartitionConvertCommandlet |
注意一个容易踩的点:Blank / First Person / Third Person / Top Down / Vehicle Advanced 这几个模板虽然用了 WP,但默认关闭了 Enable Streaming(World Settings 里可开)。
Open World 默认地图自带一个 2km × 2km 的 Landscape 与户外光照配置(天空大气、天空光、方向光、指数高度雾、体积云)。
转换命令
UnrealEditor.exe QAGame -run=WorldPartitionConvertCommandlet Playground.umap -AllowCommandletRendering| 可选参数 | 作用 |
|---|---|
-SCCProvider=(None,Perforce...) | 源码管理提供方;不加源码管理用 None |
-Verbose | 详细日志 |
-ConversionSuffix | 转换后加 _WP 后缀,保留源关卡,测试时很有用 |
-DeleteSourceLevels | 转换后删除源关卡 |
-ReportOnly | 只报告会做什么,不实际转换 |
-GenerateIni | 生成默认转换 ini |
-SkipStableGUIDValidation | 跳过不稳定 Actor GUID 校验(不稳定的 GUID 会导致多次转换结果不同,重新保存关卡可修复) |
-OnlyMergeSubLevels | 只合并子关卡到 OFPA,不启用 WP(产物可作为 WP 关卡的 Level Instance) |
-FoliageTypePath=[Path] | 关卡里若嵌了 Foliage Type,用这个导出成资产 |
转换设置可用与地图同名、同目录的 .ini 文件覆盖。
3. Actors 与网格
Actor 根据其 Is Spatially Loaded 设置(Details → World Partition)自动分配到网格单元:
| 选项 | 含义 |
|---|---|
| Runtime Grid | 放在哪个分区网格;None 则由系统选 |
| Is Spatially Loaded = true | 进入任何流式源范围内时加载(前提:不在被禁用的 Data Layer 里) |
| Is Spatially Loaded = false | 只要不在被禁用的 Data Layer 里就加载 |
因此"环境背景板、管理器类 Actor"应设为非空间加载——它们就是用来常驻的。
两条关键规则:
- One File Per Actor:Actor 存到各自的文件,改 Actor 不需要签出关卡文件,团队可并行
- 引用了其它 Actor 的 Actor 会被打包在一起、同时加载
4. 流式源(Streaming Sources)
是否加载 = f(流式源位置, 运行时网格设置)| 源 | 说明 |
|---|---|
| Player Controller | 默认就是流式源(Enable Streaming Source,默认开启) |
| World Partition Streaming Source 组件 | 自定义位置(如传送目标点预加载) |
组件选项:
| 选项 | 说明 |
|---|---|
| Target Grid | 影响哪个流式网格 |
| Shapes | 自定义形状;为空则用半径等于网格加载范围的球体 |
| Priority | 优先级;一个单元与多个源相交时取最高优先级 |
| Target State | Loaded 或 Activated;相交多个源时取最高值(Activated > Loaded) |
| Target HLOD Layer | 影响的 HLOD 层 |
| Streaming Source Enabled | 是否启用 |
蓝图接口:Enable Streaming Source / Disable Streaming Source / Is Streaming Completed(判断该组件相交的单元是否已流式完成)。
传送的推荐做法:在目标位置放一个流式源组件 → 等 Is Streaming Completed → 传送 → 关闭该组件(原位置单元随即卸载)。
5. 运行时网格设置(World Settings → World Partition Setup)
| 选项 | 说明 |
|---|---|
| Grid Name | 网格名 |
| Cell Size | 单元大小(示例 256m × 256m × 256m) |
| Loading Range | 距流式源多远加载(示例 768m 半径) |
| Block on Slow Streaming | 单元加载不够快时阻塞加载 |
| Priority / Debug Color / Preview Grids | 优先级、调试色、显示网格线 |
默认提供 2D Runtime Hash 网格。使用多个网格会对性能产生负面影响——官方明确提醒。
推荐配置参考 City Sample 的 Big City 地图。
6. 编辑器里的加载与卸载
世界初始是未加载的:关卡打开时编辑器只加载 Is Spatially Loaded = false 的 Actor(环境背景板、管理器)。这是为了让超大地图也能编辑。
| 方式 | 操作 |
|---|---|
| World Partition 窗口 | Window > World Partition > World Partition Editor,框选后右键 Load Region from Selection |
| Location Volume | 编辑器专用体积,保存关卡后在 WP 窗口里生成同名区域,右键 Load Selected Region |
编辑器快捷键
| 快捷键 | 作用 |
|---|---|
| Shift+Drag | 选区吸附到当前运行时网格大小 |
| Double Click | 相机移到该位置 |
| Shift+Double Click | 在该位置启动 PIE |
| Ctrl+Double Click | 加载该位置周围区域 |
| MMB+Drag | 测量距离 |
Minimap
Build > Build Minimap 或 WorldPartitionMinimapBuilder commandlet。如果建了却不显示,需要启用虚拟纹理支持(Edit > Project Settings → Enable virtual texture support)。
7. 构建与 Cook
| 操作 | 方式 |
|---|---|
| 生成 HLOD | Build > Build HLODs 或 WorldPartitionHLODsBuilder commandlet |
| Cook | UnrealEditor.exe QAGame -run=cook -targetplatform=WindowsNoEditor -Unversioned -map=Playground |
| 批量处理 | World Partition Builder Commandlets 框架(UWorldPartitionBuilderCommandlet / UWorldPartitionBuilder)——大世界不必整体加载就能生成 HLOD、导航数据或批量重存 Actor |
8. Blueprint 的注意事项
官方明确:Blueprint Class 与 Level Blueprint 都支持,但推荐用 Blueprint Class——因为被 Level Blueprint 引用的 Actor 会被标记为 Always Loaded。
这条很关键:一旦某个 Actor 被关卡蓝图引用,它就不参与流式了,会常驻内存。
9. 参数与控制台变量
| CVar | 作用 |
|---|---|
wp.Runtime.ToggleDrawRuntimeHash2D / 3D | 2D/3D 调试显示 |
wp.Runtime.ShowRuntimeSpatialHashGridLevel | 显示哪个网格层级 |
wp.Runtime.ShowRuntimeSpatialHashGridLevelCount | 显示几个层级 |
wp.Runtime.ShowRuntimeSpatialHashGridIndex | 显示指定网格(无效索引显示全部) |
wp.Runtime.RuntimeSpatialHashCellToSourceAngleContributionToCellImportance | 0–1,调节"流式源→单元"向量与源前向的夹角对单元重要性的贡献;越接近 0 角度影响越小 |
wp.Runtime.OverrideRuntimeSpatialHashLoadingRange | -grid=[index] -range=[值] 覆写加载范围 |
wp.Runtime.MaxLoadingLevelStreamingCells | 限制并发加载的单元数 |
wp.Runtime.HLOD 0 | 不带 HLOD 显示世界(对比排查) |
另有 Dynamic Loading Range Scaling 用于改善 PIE 性能与迭代速度。
10. 代价与权衡
| 设计 | 收益 | 代价 | 什么时候不该用 |
|---|---|---|---|
| 单持久关卡 + 网格 | 不用手工切子关卡 | 必须理解 Is Spatially Loaded 语义 | 小关卡用不上,反而增加复杂度 |
| One File Per Actor | 团队可并行编辑 | 文件数量暴涨,源码管理与 CI 要配套 | 单人小项目收益有限 |
| 多网格 | 不同内容不同粒度 | 官方明确说会负面影响性能 | 默认单网格即可 |
| 距离流式 | 只加载看得见的 | 传送/快速移动会触发大量加载 | 需要流式源组件预加载 |
| Level Blueprint 引用 | 方便 | Actor 变 Always Loaded,脱离流式 | 应改用 Blueprint Class |
| Block on Slow Streaming | 不会看到没加载完的世界 | 会卡 | 卡顿敏感的传送场景要权衡 |
11. 踩坑与排查
| 坑 | 现象 | 怎么验证 |
|---|---|---|
| 用了 WP 模板但没流式 | 世界全部加载 | 检查 World Settings 的 Enable Streaming |
| Actor 不随距离加载 | 一直存在/一直不存在 | 检查 Is Spatially Loaded;是否被禁用 Data Layer 引用 |
| Actor 常驻不卸载 | 内存下不来 | 是否被 Level Blueprint 引用(会被标记 Always Loaded) |
| 传送后一片空白 | 单元没加载 | 用流式源组件 + Is Streaming Completed |
| 快速移动卡顿 | 大量单元并发加载 | wp.Runtime.MaxLoadingLevelStreamingCells;预加载 |
| 用了多个网格变慢 | 性能下降 | 回到单网格 |
| 转换多次结果不同 | Actor GUID 不稳定 | 重新保存关卡;或用 -SkipStableGUIDValidation(只是跳过校验) |
| Minimap 不显示 | 建了但没有 | 启用虚拟纹理支持 |
| 打包后世界不对 | Cook 方式不对 | WP 地图要用 Cook commandlet |
| 编辑器打开很慢 | 加载了太多区域 | 用 Location Volume 只加载工作区 |
12. 排查顺序
1. 流式没生效?→ World Settings 的 Enable Streaming
2. 该加载没加载?→ Is Spatially Loaded / Data Layer / 是否被关卡蓝图引用
3. 该卸载没卸载?→ 同上;检查引用捆绑
4. 传送/快移问题?→ 流式源组件预加载 + Is Streaming Completed
5. 性能?→ wp.Runtime.* 可视化网格;确认单网格
6. 打包?→ 用 Cook commandlet