# 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): 已注册的脚本 DataTable。 - RegisteredMapTables (TMap): 已注册的文本映射 DataTable。 - DialogTextIndex (TMap): 按 Source 索引的对话文本映射。 - ChoiceTextIndex (TMap): 按 `Source|Target` 复合键索引的选项文本映射。 ## 使用方法 通过 GameInstance 获取子系统实例: ```cpp UGameInstance* GI = GetGameInstance(); UDialogPresentationSubsystem* DialogSubsystem = GI->GetSubsystem(); ``` 调用 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 |