2024-04-26 15:08:45 +08:00
|
|
|
|
---
|
|
|
|
|
title: World Partition(世界分区)
|
|
|
|
|
date: 2024-04-26 14:18:36
|
|
|
|
|
excerpt:
|
|
|
|
|
tags:
|
|
|
|
|
rating: ⭐
|
|
|
|
|
---
|
|
|
|
|
# 前言
|
|
|
|
|
文档地址: https://dev.epicgames.com/documentation/en-us/unreal-engine/world-partition-in-unreal-engine?application_version=5.3
|
|
|
|
|
|
|
|
|
|
- 知乎文章:
|
2024-04-27 12:19:36 +08:00
|
|
|
|
- UE5
|
|
|
|
|
- UE5 World Partition不完全指南:https://zhuanlan.zhihu.com/p/687020988
|
|
|
|
|
- UE4
|
|
|
|
|
- UE4旧版方案:WorldComposition https://zhuanlan.zhihu.com/p/270172506
|
|
|
|
|
- UE4场景流送机制:(一)场景加载: https://zhuanlan.zhihu.com/p/269493281
|
|
|
|
|
- UE4场景流送机制:(二)LevelStreamingVolume&WorldComposition https://zhuanlan.zhihu.com/p/270172506
|
2024-04-26 15:08:45 +08:00
|
|
|
|
|
2024-04-27 12:19:36 +08:00
|
|
|
|
PS.可以使用Tools-Convert Level,或者World Partition Convert Commandlet对普通关卡来进行转换。
|
|
|
|
|
|
|
|
|
|
## 调试命令
|
2024-06-17 17:25:30 +08:00
|
|
|
|
- 图形化Debug显示
|
|
|
|
|
- wp.Runtime.ToggleDrawRuntimeHash2D
|
|
|
|
|
- wp.Runtime.ToggleDrawRuntimeHash3D
|
|
|
|
|
|
2024-04-27 12:19:36 +08:00
|
|
|
|
| | |
|
|
|
|
|
|---|---|
|
|
|
|
|
|**wp.Runtime.ToggleDrawRuntimeHash2D**|开关世界分区运行时哈希的2D调试显示。|
|
|
|
|
|
|**wp.Runtime.ToggleDrawRuntimeHash3D**|开关世界分区运行时哈希的3D调试显示。|
|
|
|
|
|
|**wp.Runtime.ShowRuntimeSpatialHashGridLevel**|选择在显示世界分区运行时哈希时显示的网格级别。|
|
|
|
|
|
|**wp.Runtime.ShowRuntimeSpatialHashGridLevelCount**|选择在显示世界分区运行时哈希时要显示多少个网格级别。|
|
|
|
|
|
|**wp.Runtime.ShowRuntimeSpatialHashGridIndex**|显示世界分区运行时哈希时,显示指定的网格。无效的索引将导致显示所有网格。|
|
|
|
|
|
|**wp.Runtime.RuntimeSpatialHashCellToSourceAngleContributionToCellImportance**|取0到1之间的值,用于调节"流送源-单元网格"向量和"流送源-单元网格"向量之间的角度对单元网格重要性的贡献。该值越接近于0,角度对重要性的贡献就越小。|
|
|
|
|
|
|**wp.Runtime.OverrideRuntimeSpatialHashLoadingRange**|设置运行时加载范围。接受以下参数:<br><br>- `-grid=[index]`:设置你想影响的运行时网格。<br>- `-range=[override_loading_range]`: 设置新的运行时加载范围|
|
|
|
|
|
|**wp.Runtime.MaxLoadingLevelStreamingCells**|限制并发加载的世界分区流单元的数量。|
|
|
|
|
|
|**wp.Runtime.HLOD 0**|使用 `wp.Runtime.HLOD` 显示没有HLOD的世界。|
|
|
|
|
|
|
|
|
|
|
# 关卡实例化
|
|
|
|
|
这2个选项在Actor右键菜单中(ActorSelection)
|
|
|
|
|
- **Level Instance**
|
|
|
|
|
- 可以将任意Actor塞进去
|
|
|
|
|
- 采用**OFPA**系统保存关卡信息
|
|
|
|
|
- **Packed Level Actor**
|
|
|
|
|
- 继承自Level Instance
|
|
|
|
|
- 将所选的Actor变为component,在创建Level的同时创建一个Blueprint
|
|
|
|
|
- 内部Actor不再使用**OFPA**的方式,同时意味着整个Packed Level Actor只会按整体流送
|
2024-06-13 19:01:58 +08:00
|
|
|
|
- 在Pack时只会打包场景资产类型,功能性的蓝图会被排除
|
|
|
|
|
|
2024-08-08 15:28:21 +08:00
|
|
|
|
***相关说明文章***:https://dev.epicgames.com/community/learning/knowledge-base/r6wl/unreal-engine-world-building-guide
|
2024-06-13 19:01:58 +08:00
|
|
|
|
# 官方文档阅读笔记
|
2024-06-14 16:49:03 +08:00
|
|
|
|
## 概念
|
|
|
|
|
- **流送源**:[[#PlayerController]]是一种流送源,其他流送源可以使用 **世界分区流送源组件(UWorldPartitionStreamingSourceComponent)** 添加到关卡中,使得加载指定位置的Grid。
|
|
|
|
|
- [[#DataLayer]]:是世界分区系统中的一个子系统,用于将Actor划分到单独的层中。通过加载和卸载数据层,
|
|
|
|
|
|
|
|
|
|
|
2024-06-13 19:01:58 +08:00
|
|
|
|
## 将现有关卡转换为使用世界分区
|
|
|
|
|
可以使用**工具(Tools)> 转换关卡(Convert Level)** 菜单选项或使用世界分区转换命令:
|
2024-06-14 13:32:48 +08:00
|
|
|
|
`UnrealEditor.exe 项目名称 -run=WorldPartitionConvertCommandlet Playground.umap -AllowCommandletRendering`
|
|
|
|
|
|
|
|
|
|
## 相关设置
|
|
|
|
|
### WorldSettings
|
2024-06-14 16:49:03 +08:00
|
|
|
|
- **启用流送(Enable Streaming)**: 选项启用和禁用网格单元流送。
|
|
|
|
|
- 使用MovieRenderQueue进行渲染时,需要关闭这个选项,不然场景不会加载。
|
|
|
|
|
- ***Use External Actors***:为整个Level启用每个Actor per File存储方式。
|
2024-06-17 17:25:30 +08:00
|
|
|
|
- Preview Grid:可以在Viewport中大致预览一下每个Grid对应的Cell Size和Loading Range的设置是否合理。Preview Gird Level可以修改预览层级。
|
2024-06-14 16:49:03 +08:00
|
|
|
|
|
|
|
|
|
| | |
|
|
|
|
|
| ------------------------------------- | ----------------------------------------------------------------- |
|
|
|
|
|
| **网格名称(Grid Name)** | 包含运行时网格的名称。 |
|
|
|
|
|
| **单元大小(Cell Size)** | 确定用于生成流送关卡的网格单元的大小。在示例中, **单元大小(Cell Size)** 是256平方米。 |
|
|
|
|
|
| **加载范围(Loading Range)** | 确定与流送源距离多远的范围之内会加载单元。在上图中, **加载范围(Loading Range)** 是流送源周围768米的半径。 |
|
|
|
|
|
| **在缓慢流送时阻止(Block on Slow Streaming)** | 在网格单元加载速度不够快的情况下阻止加载。 |
|
|
|
|
|
| **优先级(Priority)** | 确定流送源的优先级。如果某个网格单元与多个流送源相交,其优先级将是所有流送源中最高的。 |
|
|
|
|
|
| **调试颜色(Debug Color)** | 确定启用 **预览网格(Preview Grids)** 时显示的网格线颜色。 |
|
|
|
|
|
| **预览网格(Preview Grids)** | 启用时,将在视口中显示网格线。 |
|
2024-06-14 13:32:48 +08:00
|
|
|
|
|
|
|
|
|
### Actor
|
2024-06-14 16:49:03 +08:00
|
|
|
|
- Runtime Grid:用于指定Actor的分区Grid名称,如果**没有指定则会自动选择**。
|
|
|
|
|
- Is Spatially Loaded:
|
|
|
|
|
- 如果启用,此Actor在未分配到禁用的数据层且在任何流送源的范围内时加载。
|
|
|
|
|
- 如果禁用,此Actor在未分配到禁用的数据层时加载。
|
|
|
|
|
- Packaging Mode:选择是否将Actor设置成Actor Per File存储方式。
|
|
|
|
|
|
|
|
|
|
### PlayerController
|
|
|
|
|
- Enable Streaming Source:将控制器作为作为**流送源**。
|
|
|
|
|
|
|
|
|
|
### UWorldPartitionStreamingSourceComponent
|
|
|
|
|
| | |
|
|
|
|
|
| ------------------------------------------------ | -------------------------------------------------------------------- |
|
|
|
|
|
| **默认可视化器加载范围(Default Visualizer Loading Range)** | 确定启用可视化器时调试可视化器网格的大小。 |
|
|
|
|
|
| **目标网格(Target Grid)** | 确定此源影响的流送网格。 |
|
|
|
|
|
| **调试颜色(Debug Color)** | 确定用于调试的颜色。 |
|
|
|
|
|
| **目标HLOD层(Target HLOD Layer)** | 确定流送源影响的HLOD层。 |
|
|
|
|
|
| **形状(Shapes)** | 确定用于为此流送源构建自定义形状的形状列表。如果为空,将使用半径等于网格加载范围的球体。 |
|
|
|
|
|
| **优先级(Priority)** | 确定流送源的优先级。如果某个网格单元与多个流送源相交,其优先级将是所有流送源中最高的。 |
|
|
|
|
|
| **流送源已启用(Streaming Source Enabled)** | 确定此组件是否已启用。 |
|
|
|
|
|
| **目标状态(Target State)** | 确定相交的网格单元应该处于的状态(已加载或已激活)。如果某个网格单元与多个流送源相交,目标状态将是最高的目标值(其中已激活高于已加载)。 |
|
|
|
|
|
蓝图函数 **Enable Streaming Source** 和 **Disable Streaming Source** 将启用和禁用此组件的流送。
|
|
|
|
|
|
|
|
|
|
### ALocationVolume
|
|
|
|
|
一种用于**加载/卸载** 指定区域的Volumn。可以在WorldPartition编辑器上点击来进行控制。也有三个蓝图函数用于控制加载与卸载:
|
|
|
|
|
- void Load()
|
|
|
|
|
- void Unload()
|
|
|
|
|
- bool IsLoaded() const
|
|
|
|
|
|
|
|
|
|
## 构建WorldPartition编辑器小地图
|
|
|
|
|
Build - Build Minimap
|
|
|
|
|
|
|
|
|
|
## DataLayer
|
|
|
|
|
官方文档:https://dev.epicgames.com/documentation/zh-cn/unreal-engine/world-partition---data-layers-in-unreal-engine?application_version=5.2
|
|
|
|
|
|
|
|
|
|
![[WorldPartition_LayerData.png|400]]
|
|
|
|
|
|
|
|
|
|
| | |
|
|
|
|
|
| ----- | ----------------------------------------------------------------------------------------- |
|
|
|
|
|
| **1** | 在关卡编辑器中切换关卡的可视性。仅当某个Actor所有关联数据层都隐藏时,它才能被隐藏。 |
|
|
|
|
|
| **2** | 表示"动态加载(Is Dynamically Loaded)"的状态。动态加载的层将会影响运行时的Actor加载。可以使用蓝图或C++代码激活这些层。 |
|
|
|
|
|
| **3** | 切换"编辑器动态加载(Editor Dynamically Loaded)"标记。在关卡编辑器中,如果Actor启用了数据层并且在世界分区中加载了编辑器单元格,将加载Actor。 |
|
|
|
|
|
| **4** | 切换此数据层中所有Actor的可见情况 |
|
|
|
|
|
| **5** | 决定启动时数据层是否在编辑器中显示。 |
|
|
|
|
|
| **6** | 决定是否应该为此数据层中的Actor生成HLOD。仅当启用"动态加载(Is Dynamically Loaded)"时可用。 |
|
|
|
|
|
| **7** | 决定启用了"动态加载(Is Dynamically Loaded)"的数据层在运行时加载、卸载还是激活。 |
|
|
|
|
|
| **8** | 决定数据层是否影响Actor的运行时加载。 |
|
2024-07-22 19:21:30 +08:00
|
|
|
|
***默认只在Editor下生效,可以将其类型切换为Runtime从而使其在游戏过程中也可以通过逻辑控制某一Layer的显隐。***
|
|
|
|
|
|
2024-06-14 16:49:03 +08:00
|
|
|
|
### 使用蓝图或者c++控制DataLayer加载
|
|
|
|
|
通过**UDataLayerSubsystem**的SetDataLayerState()来控制DataLayer的加载与卸载。
|
|
|
|
|
|
2024-07-24 12:12:11 +08:00
|
|
|
|
相关的Runtime加载控制可以参考:https://youtu.be/LI6TsZf5hh0?si=nwqz-S6DDR7MgSBT
|
2024-07-24 14:27:33 +08:00
|
|
|
|
直接通过蓝图的DataLayerSubsystem进行控制加载与显示。
|
2024-07-24 12:12:11 +08:00
|
|
|
|
|
2024-06-14 16:49:03 +08:00
|
|
|
|
# 相关CommandLet
|
|
|
|
|
- 烘焙WorldPartition:UnrealEditor.exe QAGame -run=cook -targetplatform=WindowsNoEditor -Unversioned -map=Playground
|
|
|
|
|
- HLOD Build:`UnrealEditor.exe "C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject" "/Game/ThirdPersonBP/Maps/OpenWorldTest" -run=WorldPartitionBuilderCommandlet -AllowCommandletRendering -builder=WorldPartitionHLODsBuilder`
|
|
|
|
|
- WorldPartition重命名复制:`UnrealEditor.exe "C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject" "/Game/ThirdPersonBP/Maps/OpenWorldTest" -run=WorldPartitionBuilderCommandlet -SCCProvider=None -builder=WorldPartitionRenameDuplicateBuilder -NewPackage=/Game/ThirdPersonBP/Maps/NewPackage`
|
|
|
|
|
- WorldPartition重新保存Actor:`UnrealEditor.exe "C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject" "/Game/ThirdPersonBP/Maps/OpenWorldTest" -run=WorldPartitionBuilderCommandlet -SCCProvider=None -builder=WorldPartitionResaveActorsBuilder`
|
|
|
|
|
- WorldPartition植被构建:`UnrealEditor.exe QAGame Playground.umap -run=WorldPartitionBuilderCommandlet -Builder=WorldPartitionFoliageBuilder -NewGridSize=Value`
|
|
|
|
|
- WorldPartition Nav构建:`UnrealEditor.exe "C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject" "/Game/ThirdPersonBP/Maps/OpenWorldTest" -run=WorldPartitionBuilderCommandlet -AllowCommandletRendering -builder=WorldPartitionNavigationDataBuilder -SCCProvider=None`
|
|
|
|
|
- WorldPartition智能对象构建: `UnrealEditor.exe "C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject" "/Game/ThirdPersonBP/Maps/OpenWorldTest" -run=WorldPartitionBuilderCommandlet -builder=WorldPartitionSmartObjectCollectionBuilder`
|
2024-07-17 15:31:08 +08:00
|
|
|
|
- 转换子关卡为WorldPartition:`UnrealEditor.exe -run=ConvertLevelsToExternalActorsCommandlet -nosourcecontrol -convertsublevels "Game/Maps/TestMaps/ExternalActors/MainMap`
|
|
|
|
|
|
|
|
|
|
# 修改WorldPartition场景中出现已删除物体的物体问题
|
|
|
|
|
猜测执行WorldPartitionBuilderCommandlet -builder=WorldPartitionResaveActorsBuilder。还未经过测试。
|
|
|
|
|
```bash
|
|
|
|
|
cd /d D:
|
|
|
|
|
cd D:\Projects\ASoul_UE5\Engine\Engine\Binaries\Win64
|
|
|
|
|
UnrealEditor.exe "D:\Projects\ASoul_UE5\LiveDirector\LiveDirector.uproject" "/Game/Maps/Map_WuTai_WP/Map_WuTai_WP" -run=WorldPartitionBuilderCommandlet -SCCProvider=None -builder=WorldPartitionResaveActorsBuilder
|
2024-07-17 16:51:50 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
统计文件数量
|
2024-07-17 20:01:57 +08:00
|
|
|
|
p4 sizes -s //Project/Development/LiveDirector/Content/__ExternalActors__/Maps/Map_WuTai_WP/Map_WuTai_WP/...
|
|
|
|
|
|
2024-07-19 19:45:43 +08:00
|
|
|
|
# WorldPartition Runtime Sequence驱动物体问题
|
2024-07-18 12:39:41 +08:00
|
|
|
|
1. WorldSettings关闭 EnableStreaming。所有场景Actor都会一直加载。
|
|
|
|
|
2. 对应Actor关闭Is Spatially Loaded,Actor会一直加载。
|
2024-07-18 14:19:31 +08:00
|
|
|
|
3. ~~使用WorldPartitionRuntimeStateVolumn,设置DataLayer加载即可。~~ 经过测试无效
|
2024-07-19 19:45:43 +08:00
|
|
|
|
4. ~~Sequence使用DataLayerTracker设置为Activated无效。~~
|
|
|
|
|
|
2024-07-22 11:41:38 +08:00
|
|
|
|
PS.UE大纲视图中的白色Actor是您自己放置在世界中的物品,黄色Actor是您玩游戏时由引擎生成的物品。
|
|
|
|
|
|
2024-07-19 19:45:43 +08:00
|
|
|
|
***UE-173838 Actors in Level Sequence in a World Partitioned level do not move***
|
|
|
|
|
https://issues.unrealengine.com/issue/UE-173838
|
|
|
|
|
|
|
|
|
|
但5.2已经修复这个问题。
|
2024-07-19 21:28:44 +08:00
|
|
|
|
https://github.com/EpicGames/UnrealEngine/commit/51d38831de4da7df196eecaf13f3d4b5a517f1f0
|
2024-07-19 19:45:43 +08:00
|
|
|
|
|
2024-07-23 19:39:50 +08:00
|
|
|
|
## 最终结论
|
|
|
|
|
1. Sequence不能控制DMX是因为大世界存在垃圾,需要使用上面的重新构建命令重新构建一下,问题就解决了。
|
|
|
|
|
2. 舞台DMX可以考虑,加一个Runtime DataLayer,之后塞进LiveArea中。
|
2024-07-24 12:12:11 +08:00
|
|
|
|
1. 有关DataLayer的Runtime设置可以参考:https://youtu.be/LI6TsZf5hh0?si=nwqz-S6DDR7MgSBT
|
|
|
|
|
2. 这样可以保证看不到的Actor也会被加载。
|
2024-07-24 10:30:06 +08:00
|
|
|
|
3. 在异世界地图中也用到了WorldPartitionRuntimeStateVolumn。BP_LiveArea_12_1
|
2024-07-24 12:12:11 +08:00
|
|
|
|
4. AWorldPartitionRuntimeStateVolume是字节自己实现的。Puerts与C++没有任何调用,不知道该如何使用。
|
|
|
|
|
|
|
|
|
|
### ASoul的做法
|
|
|
|
|
1. 几个通用DataLayer:
|
|
|
|
|
1. DL_AlwaysActive
|
|
|
|
|
2. DL_DMXStageAll
|
|
|
|
|
3. DL_EditorOnly
|
|
|
|
|
4. DL_LiveArea
|
|
|
|
|
2. 按照需要设置大世界专用DataLayer,主要面对的是***占用区域较大,需要全部加载的。***
|
2024-07-24 14:27:33 +08:00
|
|
|
|
3. 通过TS脚本,在进如LiveArea的时候通过DataLayerSubsystem来加载显示对应DataLayer
|
2024-07-23 19:39:50 +08:00
|
|
|
|
|
2024-07-22 16:39:09 +08:00
|
|
|
|
## 笔记
|
|
|
|
|
1. 枝江地图,针对小房间、DMX、巨蛋DMX、舞蹈室以及舞台分别使用了DataLayer。
|
|
|
|
|
2. ***LvieArea***可以关联DataLayer,并让其一起加载。比如乃琳卧室的LiveArea Map_SceneBedroom_Nailin,以及BP_LiveArea_11关联了DL_SeasideCity_StageA。
|
|
|
|
|
|
2024-07-22 19:21:30 +08:00
|
|
|
|
- 加载
|
|
|
|
|
- TsAreaListItemView.ts
|
|
|
|
|
- widget.IsLoad.OnCheckStateChanged.Add((bChecked)=>{this.OnLoadStateChanged(bChecked);});
|
|
|
|
|
- 加载:manager.LayerManager.AddViewTarget(this.preset.LevelAreaPreset.AreaGuid, this.preset.LevelAreaPreset.Description);
|
2024-07-23 17:11:54 +08:00
|
|
|
|
- ***创建ADirectorReplicationViewTarget,一个带有UWorldPartitionStreamingSourceComponent的Actor。*** 之后Attach到LiveArea上并且重合。
|
2024-07-24 10:30:06 +08:00
|
|
|
|
- class TsDirectorViewTarget extends UE.DirectorReplicationViewTarget。里面有一个定时器,判断是否加载完,加载完,调用OnLoadComplete()(客户端加载逻辑。)
|
|
|
|
|
- ***在游戏状态下把TsDirectorViewTarget删除,4级会显示没有加载这个场景。***
|
2024-07-22 19:21:30 +08:00
|
|
|
|
- ***TsLevelAreaManager.ts:LoadAreaLayer()***
|
2024-07-23 18:22:54 +08:00
|
|
|
|
- 遍历LiveArea的CareLayers,将LiveArea对应的DataLayer的状态设置为Actived。
|
2024-07-22 19:21:30 +08:00
|
|
|
|
- 销毁:manager.LayerManager.RemoveViewTarget(this.preset.LevelAreaPreset.UUID);
|
|
|
|
|
- 切换
|
|
|
|
|
- TsAreaListItemView.ts SwitchLevel()
|
|
|
|
|
- TsMapEnvironmentLayerManager:EnterLevelArea()
|
|
|
|
|
|
2024-07-23 19:39:50 +08:00
|
|
|
|
TsMapEnvironmentAsset.ts:读取JSON缓存所有的道具与资产路径,之后异步加载。
|