5.6 KiB
5.6 KiB
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 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 获取子系统实例:
UGameInstance* GI = GetGameInstance();
UDialogPresentationSubsystem* DialogSubsystem = GI->GetSubsystem<UDialogPresentationSubsystem>();
调用 ShowDialog 触发脚本执行:
// Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp:8-17
DialogSubsystem->ShowDialog(ExecutorWidget, FName("StartNode"));
注册 DataTable 和 MapTable:
// Plugins/Dialog/Source/Dialog/Private/DialogPresentationSubsystem.cpp:43,56
DialogSubsystem->RegisterDataTable(FName("Chapter1"), ScriptTable);
DialogSubsystem->RegisterMapTable(FName("Chapter1"), MapTable);
查询对话文本:
// 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 |