Files
loneseDocument/Plugins/Dialog/UDialogPresentationSubsystem.md
meishibiezb 29a3f77908 init
2026-06-04 21:44:13 +08:00

86 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# UDialogPresentationSubsystem
## 基本信息
- **类型**: UCLASS
- **父类**: UGameInstanceSubsystem
- **源文件**: Plugins/Dialog/Source/Dialog/Public/DialogPresentationSubsystem.h
- **模块**: Dialog
## 功能概述
GameInstance 级别的对话数据中心注册表。管理脚本数据FDialogPresentationScriptData和映射表FDialogTextData的 DataTable 注册。构建 O(1) 文本查找索引。ShowDialog 将所有环节串联起来:通过 StructID 查找脚本、注入 ScriptID、调用执行器的 ExecutePresentationScript。
## 设计用意
对话系统的数据访问层。使用 UGameInstanceSubsystem 以获得持久生命周期。支持多个 DataTable按章节、按 NPC 等)。通过预构建的哈希映射实现 O(1) 文本查找,满足频繁的游戏查询需求。将数据与执行解耦。
## 职责范围
对话数据中心注册表与查找。注册/注销 DataTable。构建文本索引。通过 StructID 解析脚本。不执行脚本(委托给执行器),也不解析 JSON使用 UPresentationJsonLibrary
## 项目内依赖
| 依赖项 | 关系 | 源文件 |
|--------|------|--------|
| FDialogTextData | 前向声明 | Plugins/Dialog/Source/Dialog/Public/DialogPresentationSubsystem.h:11 |
| IPresentationScriptExecutor | 前向声明(参数) | Plugins/Dialog/Source/Dialog/Public/DialogPresentationSubsystem.h:32 |
| FDialogPresentationScriptData | #include(在 .cpp 中) | Plugins/Dialog/Source/Dialog/Public/DialogPresentationScript.h |
## 对外接口
UGameInstanceSubsystem 派生类,所有方法均为 UFUNCTION(BlueprintCallable),可从 C++ 和蓝图调用。UE 引擎自动创建实例(每个 GameInstance 一个),无需手动实例化。
脚本执行:
- **ShowDialog(const TScriptInterface<IPresentationScriptExecutor> Executor, const FName StructID)**: 核心入口。在所有已注册的 DataTable 中按 StructID 查找 FDialogPresentationScriptData注入 ScriptID然后调用 Executor 的 ExecutePresentationScript 接口方法。
数据查询:
- **GetDialogPresentationScriptData(const FName StructID)**: 遍历 RegisteredDataTables返回第一个匹配 StructID 的行。返回时会注入 ScriptID 字段。
- **GetDialogTextFromMapTable(FName Source)**: 从 DialogTextIndex 中按 Source 查找对话文本O(1) 复杂度。首次调用时若索引未构建则自动触发 BuildIndexes()。
- **GetChoiceTextFromMapTable(FName Source, FName Target)**: 从 ChoiceTextIndex 中按复合键 `Source|Target` 查找选项文本数组O(1) 复杂度。首次调用时若索引未构建则自动触发 BuildIndexes()。
DataTable 管理:
- **RegisterDataTable(const FName TableName, UDataTable* DataTable)**: 注册脚本 DataTable。TableName 仅供标识,查找时遍历所有已注册表。
- **UnregisterDataTable(const FName TableName)**: 注销脚本 DataTable。
- **RegisterMapTable(const FName TableName, UDataTable* DataTable)**: 注册文本映射 DataTableFDialogTextData。注册时自动调用 BuildIndexes() 重建索引。
- **UnregisterMapTable(const FName TableName)**: 注销文本映射 DataTable 并重建索引。
内部状态(对外不可见):
- RegisteredDataTables (TMap<FName, UDataTable*>): 已注册的脚本 DataTable。
- RegisteredMapTables (TMap<FName, UDataTable*>): 已注册的文本映射 DataTable。
- DialogTextIndex (TMap<FName, FDialogTextData>): 按 Source 索引的对话文本映射。
- ChoiceTextIndex (TMap<FName, FHelperArray>): 按 `Source|Target` 复合键索引的选项文本映射。
## 使用方法
通过 GameInstance 获取子系统实例:
```cpp
UGameInstance* GI = GetGameInstance();
UDialogPresentationSubsystem* DialogSubsystem = GI->GetSubsystem<UDialogPresentationSubsystem>();
```
调用 ShowDialog 触发脚本执行:
```cpp
// Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp:8-17
DialogSubsystem->ShowDialog(ExecutorWidget, FName("StartNode"));
```
注册 DataTable 和 MapTable
```cpp
// Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp:43,56
DialogSubsystem->RegisterDataTable(FName("Chapter1"), ScriptTable);
DialogSubsystem->RegisterMapTable(FName("Chapter1"), MapTable);
```
查询对话文本:
```cpp
// Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp:71-81
FDialogTextData Text = DialogSubsystem->GetDialogTextFromMapTable(FName("Node_01"));
```
## 用例
| 文件 | 行号 | 用途 |
|------|------|------|
| Plugins/Dialog/Source/Dialog/Public/DialogPresentationSubsystem.h | 26-70 | 类定义:所有公共方法声明和私有成员 |
| Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp | 8-17 | ShowDialog 实现:校验接口 + 调用 Execute_ExecutePresentationScript |
| Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp | 20-41 | GetDialogPresentationScriptData 实现:遍历已注册表查找行 |
| Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp | 43-53 | RegisterDataTable / UnregisterDataTable 实现 |
| Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp | 56-68 | RegisterMapTable / UnregisterMapTable 实现(含自动索引重建) |
| Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp | 71-81 | GetDialogTextFromMapTable 实现O(1) 查找 |
| Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp | 84-96 | GetChoiceTextFromMapTable 实现:按复合键 O(1) 查找 |
| Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp | 98-127 | BuildIndexes 实现:遍历 MapTable 构建 DialogTextIndex 和 ChoiceTextIndex |
| Document/Content/Blueprints/WBP_TestUI.md | 16,24 | WBP_TestUI 通过 UDialogPresentationSubsystem 管理 DataTable |