86 lines
5.6 KiB
Markdown
86 lines
5.6 KiB
Markdown
# 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)**: 注册文本映射 DataTable(FDialogTextData)。注册时自动调用 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 |
|