SuperAPI AI 工具集

levels-and-world-partition

编程与开发

查看项目

更新于 11-06 16:23

技能介绍

用途

本技能用于指导 Unreal Engine C++ 项目中的世界组织与流式加载,帮助开发者把关卡内容拆分、按需加载,从而控制内存占用并支持大型或开放世界。资料同时覆盖 UE5 的 World Partition 与旧式子关卡(Sublevel)两套机制。

核心概念

UWorld 是运行中的游戏世界,始终包含一个常驻关卡 PersistentLevel(UWorld::PersistentLevel),以及任意数量的流式关卡。在游戏代码中可通过 AActor::GetWorld() 取得 UWorld;UWorld::GetWorldPartition() 返回 UWorldPartition(非 WP 世界为 null);UWorld::GetDataLayerManager() 返回 UDataLayerManager(仅 World Partition 世界可用)。

结构示意:UWorld 下包含 PersistentLevel、UWorldPartition(若启用,内含运行时网格、UDataLayerManager、actor 描述符注册表)以及 StreamingLevels 数组(旧式子关卡时存在,每个子关卡对应一个 ULevelStreaming)。

两套流式加载模型

  • World Partition(现代):适用于开放世界和大型关卡,由引擎根据流式源自动加载/卸载网格单元格。
  • 子关卡(旧式/显式):适用于小型游戏和手工划分区域,需要在代码、蓝图或 Streaming Volume 中显式加载/卸载具名关卡。

资料指出 World Composition(UE5 之前)已被 World Partition 取代,新项目不应再使用。

World Partition 细节

World Partition 把整个世界存放在单个常驻关卡中,运行时用空间哈希网格把世界划分为单元格;随着流式源在世界上移动,单元格自动加载与卸载。网格参数在 World Settings → World Partition Setup 配置,关键字段包括 Cell Size(单元格空间尺寸,例如默认 25 600 cm = 256 m)、Loading Range(流式源周围加载半径)、Block on Slow Streaming(加载过慢时阻塞游戏线程)。

APlayerController 默认是流式源(可在其 Details 中通过 Enable Streaming Source 关闭)。其他视角(过场相机、传送目的地等)可给任意 actor 添加 UWorldPartitionStreamingSourceComponent,并在运行时调用 EnableStreamingSource、DisableStreamingSource,或用 IsStreamingCompleted 轮询是否加载完成(例如传送玩家前)。资料给出源文件行号:WorldPartitionStreamingSourceComponent.h:28/32/44。

Data Layers

Data Layers 把一组 actor 组织为整体,可成组启用/禁用。类型分为 Runtime(运行时切换,用于昼夜、破坏阶段、任务状态)与 Editor(仅编辑器组织用,不可运行时修改)。Data Layer 以 UDataLayerAsset(UDataAsset 子类)定义;每个世界创建由 UDataLayerManager 拥有的 UDataLayerInstance 对象,运行时状态为 Unloaded → Loaded → Activated。

C++ 修改状态(5.3+)示例:通过 GetWorld()->GetDataLayerManager() 取得管理器,用 GetDataLayerInstanceFromAsset 找到实例,再调用 SetDataLayerInstanceRuntimeState 并传入 EDataLayerRuntimeState::Activated。资料说明 EDataLayerRuntimeState 取值有 Unloaded、Loaded、Activated;UDataLayerSubsystem 仅为蓝图兼容保留,自 5.3 起弃用,新 C++ 代码应使用 UDataLayerManager。

Level Instances 与 Packed Level Actors

Level Instance(ALevelInstance)把 .umap 作为可复用预制体嵌入,一处编辑传播到所有实例。运行时,使用 OFPA 的关卡默认嵌入 World Partition 网格;不使用 OFPA 的关卡退回关卡流式模式,运行时开销更高。Packed Level Actor(APackedLevelActor,ALevelInstance 子类)把 Level Instance 中所有静态网格烘焙为单个由 ISM 支撑的 actor,适合静态建筑或密集视觉组合。两者都参与 World Partition Data Layers:Level Instance 内 actor 继承赋给该 Level Instance Actor 的 Data Layer。

One File Per Actor(OFPA)

启用 World Partition 后,每个 actor 序列化到 ExternalActors/ 下独立文件。其影响包括:多名开发者可编辑不同 actor 而无需锁定关卡文件;版本控制变更列表包含大量小文件与编码名,可用编辑器内 View Changelist 窗口查看可读名;cook 时所有外部 actor 文件会重新嵌入关卡包。Level Instance 中非 OFPA actor 在运行时回退到关卡流式模式。OFPA 随 World Partition 自动启用;对非分区关卡可设置 bUseExternalActors = true(Level.h:445)启用。

旧式子关卡流式加载

对未使用 World Partition 的项目,可用 UGameplayStatics 加载/卸载子关卡:LoadStreamLevel(参数含 bMakeVisible、bShouldBlockOnLoad,异步时不阻塞)与 UnloadStreamLevel(参数含 FLatentActionInfo、bShouldBlockOnUnload)。ALevelStreamingVolume 可在玩家进入/离开时自动触发加载/卸载,适合离散区域的小型游戏。ULevelStreaming(LevelStreaming.h:138)跟踪每个子关卡的加载状态,UWorld::StreamingLevels 持有该数组。

选型指南

  • 小型/线性游戏、明确区域:常驻关卡 + 旧式流式子关卡。
  • 开放世界或超大关卡:World Partition(默认单元格网格)。
  • 多变世界状态:运行时 Data Layers。
  • 可复用重复结构:Level Instances / Packed Level Actors。
  • 开放世界中的 Level Instance:带 OFPA 的 ALevelInstance(Embedded 模式)。

限制与常见陷阱

资料列出的陷阱包括:所有内容放在一个关卡会导致内存暴涨;指向另一 WP 单元格 actor 的硬指针在该单元格卸载后失效,应改用 TSoftObjectPtr 并通过异步加载/资产管理重新获取;游戏线程上的阻塞加载(bShouldBlockOnLoad = true)会造成卡顿,应异步流式加载并以潜回回调或 IsStreamingCompleted 把关;OFPA 加版本控制会产生大量小文件,应配置生成目录的忽略规则且不要从编辑器外提交;新项目勿用 World Composition;5.3+ 全部路径应使用 UDataLayerManager;被 Level Blueprint 引用的 actor 会被视为 Always Loaded,破坏流式加载,应优先使用 Blueprint 类;Data Layer 状态复制规则要求未过滤(服务器+客户端)层在服务器设置、Client-Only 层在客户端设置,设置错侧无效。

版本说明

UE 5.0+ 所有 Games 类项目模板默认启用 World Partition 与 OFPA;可在 World Settings → Enable Streaming 关闭流式加载而保留 WP 架构(适合仍想用 OFPA 的小游戏)。UDataLayerSubsystem 于 5.3 弃用;UWorldPartitionStreamingSourceComponent 的 TargetHLODLayers 于 5.4 弃用,改用 TargetGrids;ULevelStreaming 的 ECurrentState 于 5.2 弃用,改用 ELevelStreamingState。资料中的引擎源码行号基于 UE 5.8。