添加对话系统插件
@ -8040,6 +8040,26 @@
|
|||||||
{
|
{
|
||||||
"Path": "$(ProjectDir)/Plugins/DeskMode/Binaries/Win64/UnrealEditor.modules",
|
"Path": "$(ProjectDir)/Plugins/DeskMode/Binaries/Win64/UnrealEditor.modules",
|
||||||
"Type": "RequiredResource"
|
"Type": "RequiredResource"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Path": "$(ProjectDir)/Plugins/Dialogue/Binaries/Win64/UnrealEditor-Dialogue.dll",
|
||||||
|
"Type": "DynamicLibrary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Path": "$(ProjectDir)/Plugins/Dialogue/Binaries/Win64/UnrealEditor-Dialogue.pdb",
|
||||||
|
"Type": "SymbolFile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Path": "$(ProjectDir)/Plugins/Dialogue/Binaries/Win64/UnrealEditor-DialogueEditor.dll",
|
||||||
|
"Type": "DynamicLibrary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Path": "$(ProjectDir)/Plugins/Dialogue/Binaries/Win64/UnrealEditor-DialogueEditor.pdb",
|
||||||
|
"Type": "SymbolFile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Path": "$(ProjectDir)/Plugins/Dialogue/Binaries/Win64/UnrealEditor.modules",
|
||||||
|
"Type": "RequiredResource"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"RuntimeDependencies": [
|
"RuntimeDependencies": [
|
||||||
@ -33775,6 +33795,10 @@
|
|||||||
"Path": "$(ProjectDir)/Plugins/DeskMode/DeskMode.uplugin",
|
"Path": "$(ProjectDir)/Plugins/DeskMode/DeskMode.uplugin",
|
||||||
"Type": "UFS"
|
"Type": "UFS"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Path": "$(ProjectDir)/Plugins/Dialogue/Dialogue.uplugin",
|
||||||
|
"Type": "UFS"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"Path": "$(ProjectDir)/ProjectFish.uproject",
|
"Path": "$(ProjectDir)/ProjectFish.uproject",
|
||||||
"Type": "UFS"
|
"Type": "UFS"
|
||||||
@ -33844,6 +33868,7 @@
|
|||||||
"DatasmithContent",
|
"DatasmithContent",
|
||||||
"DeformerGraph",
|
"DeformerGraph",
|
||||||
"DeskMode",
|
"DeskMode",
|
||||||
|
"Dialogue",
|
||||||
"DumpGPUServices",
|
"DumpGPUServices",
|
||||||
"EOSShared",
|
"EOSShared",
|
||||||
"EditorDataStorage",
|
"EditorDataStorage",
|
||||||
|
|||||||
BIN
ProjectFish/Content/DataAssets/Dialogue/5.uasset
Normal file
BIN
ProjectFish/Content/DataAssets/Dialogue/Condition_False.uasset
Normal file
BIN
ProjectFish/Content/DataAssets/Dialogue/Condition_True.uasset
Normal file
BIN
ProjectFish/Content/Maps/TestDialogue.umap
Normal file
BIN
ProjectFish/Content/UI/TestUI/DialogueText.uasset
Normal file
BIN
ProjectFish/Content/UI/TestUI/TestDialogueWidget.uasset
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"BuildId": "37670630",
|
||||||
|
"Modules":
|
||||||
|
{
|
||||||
|
"Dialogue": "UnrealEditor-Dialogue.dll",
|
||||||
|
"DialogueEditor": "UnrealEditor-DialogueEditor.dll"
|
||||||
|
}
|
||||||
|
}
|
||||||
29
ProjectFish/Plugins/Dialogue/Dialogue.uplugin
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"FileVersion": 3,
|
||||||
|
"Version": 1,
|
||||||
|
"VersionName": "1.0",
|
||||||
|
"FriendlyName": "Dialogue",
|
||||||
|
"Description": "",
|
||||||
|
"Category": "Other",
|
||||||
|
"CreatedBy": "",
|
||||||
|
"CreatedByURL": "",
|
||||||
|
"DocsURL": "",
|
||||||
|
"MarketplaceURL": "",
|
||||||
|
"SupportURL": "",
|
||||||
|
"CanContainContent": true,
|
||||||
|
"IsBetaVersion": false,
|
||||||
|
"IsExperimentalVersion": false,
|
||||||
|
"Installed": false,
|
||||||
|
"Modules": [
|
||||||
|
{
|
||||||
|
"Name": "Dialogue",
|
||||||
|
"Type": "Runtime",
|
||||||
|
"LoadingPhase": "Default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "DialogueEditor",
|
||||||
|
"Type": "Editor",
|
||||||
|
"LoadingPhase": "Default"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
ProjectFish/Plugins/Dialogue/Resources/Icon128.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
ProjectFish/Plugins/Dialogue/Resources/condition.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
ProjectFish/Plugins/Dialogue/Resources/dialogue_16.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
ProjectFish/Plugins/Dialogue/Resources/dialogue_64.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
ProjectFish/Plugins/Dialogue/Resources/event.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
ProjectFish/Plugins/Dialogue/Resources/npcNode.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
ProjectFish/Plugins/Dialogue/Resources/playerNode.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
ProjectFish/Plugins/Dialogue/Resources/sound.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
ProjectFish/Plugins/Dialogue/Resources/startNode.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
using UnrealBuildTool;
|
||||||
|
|
||||||
|
public class Dialogue : ModuleRules
|
||||||
|
{
|
||||||
|
public Dialogue(ReadOnlyTargetRules Target) : base(Target)
|
||||||
|
{
|
||||||
|
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
//test
|
||||||
|
OptimizeCode = CodeOptimization.Never;
|
||||||
|
PublicIncludePaths.AddRange(
|
||||||
|
new string[] {
|
||||||
|
// ... add public include paths required here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
PrivateIncludePaths.AddRange(
|
||||||
|
new string[] {
|
||||||
|
// ... add other private include paths required here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
PublicDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"Core",
|
||||||
|
// ... add other public dependencies that you statically link with here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
PrivateDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"CoreUObject",
|
||||||
|
"Engine",
|
||||||
|
"Slate",
|
||||||
|
"SlateCore",
|
||||||
|
// ... add private dependencies that you statically link with here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
DynamicallyLoadedModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
// ... add any modules that your module loads dynamically here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "Dialogue.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "FDialogueModule"
|
||||||
|
|
||||||
|
void FDialogueModule::StartupModule()
|
||||||
|
{
|
||||||
|
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueModule::ShutdownModule()
|
||||||
|
{
|
||||||
|
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||||
|
// we call this function before unloading the module.
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
|
|
||||||
|
IMPLEMENT_MODULE(FDialogueModule, Dialogue)
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "DialogueAsset.h"
|
||||||
|
|
||||||
|
#include "UObject/ObjectSaveContext.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool UDialogueConditions::IsConditionMet_Implementation()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDialogueAsset::BeginDialogue()
|
||||||
|
{
|
||||||
|
CurrentNode = NodeDatas[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
FText UDialogueAsset::GetNextNodeText()
|
||||||
|
{
|
||||||
|
if (CurrentNode->OutputPins.Num() > 0 && CurrentNode->OutputPins[0]->Connections.Num() > 0)
|
||||||
|
{
|
||||||
|
UDialogueRuntimePin* Connection = CurrentNode->OutputPins[0]->Connections[0];
|
||||||
|
UDialogueRuntimeNode* ConnectionParent = Connection->Parent;
|
||||||
|
|
||||||
|
if (ConnectionParent->NodeType == EDialogueNodeType::NPC)
|
||||||
|
{
|
||||||
|
//处理下一个对话是npc的情况
|
||||||
|
for (auto Pin: CurrentNode->OutputPins[0]->Connections)
|
||||||
|
{
|
||||||
|
UDialogueRuntimeNode* ConnectionNode = Pin->Parent;
|
||||||
|
if (ConnectionNode->NodeData->Conditionses.Num() != 0)
|
||||||
|
{
|
||||||
|
//判断是否符合条件
|
||||||
|
bool ConditionMet = false;
|
||||||
|
for (auto Condition: ConnectionNode->NodeData->Conditionses)
|
||||||
|
{
|
||||||
|
ConditionMet = ConditionMet || Condition->IsConditionMet();
|
||||||
|
}
|
||||||
|
if (ConditionMet)
|
||||||
|
{
|
||||||
|
CurrentNode = ConnectionNode;
|
||||||
|
return ConnectionNode->NodeData->Text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentNode = ConnectionNode;
|
||||||
|
return ConnectionNode->NodeData->Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (ConnectionParent->NodeType == EDialogueNodeType::Player)
|
||||||
|
{
|
||||||
|
//处理下一个对话是玩家选项的情况
|
||||||
|
TArray<FText> Options;
|
||||||
|
for (UDialogueRuntimePin* Pin : CurrentNode->OutputPins[0]->Connections)
|
||||||
|
{
|
||||||
|
Options.Add(Pin->Parent->NodeData->Text);
|
||||||
|
}
|
||||||
|
OnNeedPlayerSelect.Broadcast(Options);
|
||||||
|
//返回值不变
|
||||||
|
return CurrentNode->NodeData->Text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("DialogueNode has no output pin"));
|
||||||
|
}
|
||||||
|
return FText::FromString(TEXT(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDialogueAsset::PlayerSelect(int32 index)
|
||||||
|
{
|
||||||
|
CurrentNode = CurrentNode->OutputPins[0]->Connections[index]->Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDialogueAsset::PreSave(FObjectPreSaveContext saveContext)
|
||||||
|
{
|
||||||
|
if (OnPreSaveListener)
|
||||||
|
{
|
||||||
|
OnPreSaveListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "DialogueSettings.h"
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Modules/ModuleManager.h"
|
||||||
|
|
||||||
|
class FDialogueModule : public IModuleInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** IModuleInterface implementation */
|
||||||
|
virtual void StartupModule() override;
|
||||||
|
virtual void ShutdownModule() override;
|
||||||
|
};
|
||||||
@ -0,0 +1,124 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/DataAsset.h"
|
||||||
|
#include "DialogueAsset.generated.h"
|
||||||
|
|
||||||
|
UCLASS(Blueprintable, BlueprintType, abstract, EditInlineNew, HideCategories = ("DoNotShow"), CollapseCategories, AutoExpandCategories = ("Default"))
|
||||||
|
class DIALOGUE_API UDialogueConditions : public UObject
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Dialogue Conditions")
|
||||||
|
bool IsConditionMet();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
UENUM()
|
||||||
|
enum class EDialogueNodeType {
|
||||||
|
None,
|
||||||
|
Root,
|
||||||
|
NPC,
|
||||||
|
Player
|
||||||
|
};
|
||||||
|
UCLASS()
|
||||||
|
class DIALOGUE_API UDialogueRuntimePin : public UObject
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY()
|
||||||
|
FName PinName;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
FGuid PinId;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
TArray<UDialogueRuntimePin*> Connections;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
class UDialogueRuntimeNode* Parent = nullptr;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
int32 Direction;
|
||||||
|
bool operator ==(const UDialogueRuntimePin& other) const
|
||||||
|
{
|
||||||
|
return PinId == other.PinId;
|
||||||
|
}
|
||||||
|
friend uint32 GetTypeHash(const UDialogueRuntimePin& other)
|
||||||
|
{
|
||||||
|
return GetTypeHash(other.PinId);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class DIALOGUE_API UDialogueNodeData_Base : public UObject
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dialogue Node", meta = (MultiLine = true))
|
||||||
|
FText Text;
|
||||||
|
|
||||||
|
UPROPERTY(Instanced, EditAnywhere, BlueprintReadWrite, Category = "Dialogue Node")
|
||||||
|
TArray<UDialogueConditions*> Conditionses;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class DIALOGUE_API UDialogueRuntimeNode : public UObject
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY()
|
||||||
|
UDialogueRuntimePin* InputPin;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
TArray<UDialogueRuntimePin*> OutputPins;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
FVector2D Position;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
UDialogueNodeData_Base* NodeData = nullptr;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
EDialogueNodeType NodeType = EDialogueNodeType::None;
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FNeedPlayeSelectDelegate, const TArray<FText>&, Options);
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS(BlueprintType)
|
||||||
|
class DIALOGUE_API UDialogueAsset : public UDataAsset
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
UFUNCTION(BlueprintCallable, Category = Dialogue)
|
||||||
|
void BeginDialogue();
|
||||||
|
UFUNCTION(BlueprintPure, Category = Dialogue)
|
||||||
|
FText GetNextNodeText();
|
||||||
|
UFUNCTION(BlueprintCallable, Category = Dialogue)
|
||||||
|
void PlayerSelect(int32 index);
|
||||||
|
|
||||||
|
public:
|
||||||
|
//设置修改过程中回调
|
||||||
|
void SetPreSaveListener(std::function<void()> InPreSaveListener) { OnPreSaveListener = InPreSaveListener; }
|
||||||
|
virtual void PreSave(FObjectPreSaveContext saveContext) override;
|
||||||
|
public:
|
||||||
|
UPROPERTY(BlueprintAssignable, Category=Dialogue)
|
||||||
|
FNeedPlayeSelectDelegate OnNeedPlayerSelect;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Dialogue)
|
||||||
|
TArray<UDialogueRuntimeNode*> NodeDatas;
|
||||||
|
private:
|
||||||
|
UDialogueRuntimeNode* CurrentNode = nullptr;
|
||||||
|
std::function<void()> OnPreSaveListener = nullptr;
|
||||||
|
};
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "UObject/Object.h"
|
||||||
|
#include "DialogueSettings.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS(Config = Dialogue, DefaultConfig)
|
||||||
|
class DIALOGUE_API UDialogueSettings : public UObject
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
};
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
using UnrealBuildTool;
|
||||||
|
|
||||||
|
public class DialogueEditor : ModuleRules
|
||||||
|
{
|
||||||
|
public DialogueEditor(ReadOnlyTargetRules Target) : base(Target)
|
||||||
|
{
|
||||||
|
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
//test
|
||||||
|
OptimizeCode = CodeOptimization.Never;
|
||||||
|
PublicDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"Core",
|
||||||
|
"AssetTools"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
PrivateDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"CoreUObject",
|
||||||
|
"Engine",
|
||||||
|
"Slate",
|
||||||
|
"SlateCore",
|
||||||
|
"Dialogue",
|
||||||
|
"Projects",
|
||||||
|
"UnrealEd",
|
||||||
|
"GraphEditor",
|
||||||
|
"Kismet"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,345 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#include "DialogueAssetEditor.h"
|
||||||
|
#include "DialogueGraph.h"
|
||||||
|
#include "DialogueGraphSchema.h"
|
||||||
|
#include "DialogueEditorMode.h"
|
||||||
|
#include "DialogueGraphPanelNodeFactory.h"
|
||||||
|
#include "DialogueGraphPanelPinFactory.h"
|
||||||
|
#include "EdGraphUtilities.h"
|
||||||
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
|
#include "GraphEditorActions.h"
|
||||||
|
#include "Framework/Commands/GenericCommands.h"
|
||||||
|
#include "IDetailsView.h"
|
||||||
|
#include "Node/DialogueGraphNode_Base.h"
|
||||||
|
#include "Node/DialogueGraphNode_NPC.h"
|
||||||
|
#include "Node/DialogueGraphNode_Player.h"
|
||||||
|
#include "Node/DialogueGraphNode_Root.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "DialogueEditorToolkit"
|
||||||
|
|
||||||
|
const FName DialogueEditorAppName = FName(TEXT("DialogueEditorApp"));
|
||||||
|
|
||||||
|
void FDialogueAssetEditor::OnClose()
|
||||||
|
{
|
||||||
|
SaveGraphData();
|
||||||
|
DialogueBeingEdited->SetPreSaveListener(nullptr);
|
||||||
|
FWorkflowCentricApplication::OnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
FDialogueAssetEditor::FDialogueAssetEditor()
|
||||||
|
: DialogueGraph(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FDialogueAssetEditor::~FDialogueAssetEditor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FText FDialogueAssetEditor::GetBaseToolkitName() const
|
||||||
|
{
|
||||||
|
return IsValid(DialogueBeingEdited) ? FText::FromString(DialogueBeingEdited->GetName()) : LOCTEXT("AppLabel", "Dialogue Editor");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FDialogueAssetEditor::InitDialogueEditor(const EToolkitMode::Type Mode,
|
||||||
|
const TSharedPtr<IToolkitHost>& InitToolkitHost, TObjectPtr<UDialogueAsset> InitDialogueAsset)
|
||||||
|
{
|
||||||
|
DialogueBeingEdited = InitDialogueAsset;
|
||||||
|
//修改过程中保存
|
||||||
|
DialogueBeingEdited->SetPreSaveListener([this] () { SaveGraphData();; });
|
||||||
|
// 注册命令
|
||||||
|
FGenericCommands::Register();
|
||||||
|
FGraphEditorCommands::Register();
|
||||||
|
BindGraphCommands();
|
||||||
|
|
||||||
|
//注册节点的创建
|
||||||
|
FEdGraphUtilities::RegisterVisualNodeFactory(MakeShareable(new FDialogueGraphPanelNodeFactory()));
|
||||||
|
FEdGraphUtilities::RegisterVisualPinFactory(MakeShareable(new FDialogueGraphPanelPinFactory()));
|
||||||
|
|
||||||
|
// 创建图表
|
||||||
|
DialogueGraph = FBlueprintEditorUtils::CreateNewGraph(
|
||||||
|
DialogueBeingEdited.Get(),
|
||||||
|
NAME_None,
|
||||||
|
UDialogueGraph::StaticClass(),
|
||||||
|
UDialogueGraphSchema::StaticClass()
|
||||||
|
);
|
||||||
|
|
||||||
|
TArray<UObject*> ObjectsToEdit;
|
||||||
|
ObjectsToEdit.Add(InitDialogueAsset);
|
||||||
|
|
||||||
|
// 初始化编辑器
|
||||||
|
InitAssetEditor(
|
||||||
|
Mode,
|
||||||
|
InitToolkitHost,
|
||||||
|
DialogueEditorAppName,
|
||||||
|
FTabManager::FLayout::NullLayout,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
ObjectsToEdit
|
||||||
|
);
|
||||||
|
|
||||||
|
// 添加应用模式
|
||||||
|
AddApplicationMode(TEXT("DialogueEditorMode"), MakeShareable(new FDialogueEditorMode(SharedThis(this))));
|
||||||
|
SetCurrentMode(TEXT("DialogueEditorMode"));
|
||||||
|
|
||||||
|
//加载资源中的数据节点
|
||||||
|
LoadGraphData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueAssetEditor::SetDetailsView(TSharedPtr<IDetailsView> InDetailsView)
|
||||||
|
{
|
||||||
|
DetailsView = InDetailsView;
|
||||||
|
if (DetailsView.IsValid())
|
||||||
|
{
|
||||||
|
DetailsView->OnFinishedChangingProperties().AddSP(this, &FDialogueAssetEditor::OnNodeDetailViewPropertiesUpdated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueAssetEditor::OnGraphSelectionChanged(const FGraphPanelSelectionSet& Selection)
|
||||||
|
{
|
||||||
|
if (!DetailsView.IsValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (UDialogueGraphNode_Base* SelectedNode = GetSelectedNode(Selection))
|
||||||
|
{
|
||||||
|
DetailsView->SetObject(SelectedNode->GetDialogueNodeData());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DetailsView->SetObject(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueAssetEditor::SaveGraphData()
|
||||||
|
{
|
||||||
|
if (!DialogueBeingEdited || !DialogueGraph)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TArray<std::pair<FGuid, FGuid>> Connections;
|
||||||
|
TMap<FGuid, UDialogueRuntimePin*> IdToPinMap;
|
||||||
|
DialogueBeingEdited->NodeDatas.Empty();
|
||||||
|
for (UEdGraphNode* EditorNode : DialogueGraph->Nodes)
|
||||||
|
{
|
||||||
|
UDialogueRuntimeNode* RuntimeNode = NewObject<UDialogueRuntimeNode>(DialogueBeingEdited);
|
||||||
|
RuntimeNode->Position = FVector2D(EditorNode->NodePosX, EditorNode->NodePosY);
|
||||||
|
|
||||||
|
for (UEdGraphPin* EditorPin : EditorNode->Pins)
|
||||||
|
{
|
||||||
|
UDialogueRuntimePin* RuntimePin = NewObject<UDialogueRuntimePin>(RuntimeNode);
|
||||||
|
RuntimePin->PinName = EditorPin->PinName;
|
||||||
|
RuntimePin->PinId = EditorPin->PinId;
|
||||||
|
RuntimePin->Parent = RuntimeNode;
|
||||||
|
RuntimePin->Direction = EditorPin->Direction;
|
||||||
|
|
||||||
|
if (EditorPin->HasAnyConnections())
|
||||||
|
{
|
||||||
|
std::pair<FGuid, FGuid> Connection = std::make_pair(EditorPin->PinId, EditorPin->LinkedTo[0]->PinId);
|
||||||
|
Connections.Add(Connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
IdToPinMap.Add(EditorPin->PinId, RuntimePin);
|
||||||
|
if (RuntimePin->Direction == EGPD_Input)
|
||||||
|
{
|
||||||
|
RuntimeNode->InputPin = RuntimePin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RuntimeNode->OutputPins.Add(RuntimePin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UDialogueGraphNode_Base* EditorDialogueNode = Cast<UDialogueGraphNode_Base>(EditorNode);
|
||||||
|
RuntimeNode->NodeData = DuplicateObject(EditorDialogueNode->GetDialogueNodeData(), DialogueBeingEdited);
|
||||||
|
RuntimeNode->NodeType = EditorDialogueNode->GetDialogueNodeType();
|
||||||
|
|
||||||
|
DialogueBeingEdited->NodeDatas.Add(RuntimeNode);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::pair<FGuid, FGuid> Connection : Connections)
|
||||||
|
{
|
||||||
|
UDialogueRuntimePin* Pin1 = IdToPinMap[Connection.first];
|
||||||
|
UDialogueRuntimePin* Pin2 = IdToPinMap[Connection.second];
|
||||||
|
if (!Pin1->Connections.Contains(Pin2))
|
||||||
|
{
|
||||||
|
Pin1->Connections.Add(Pin2);
|
||||||
|
if (Pin1->Direction == EGPD_Input)
|
||||||
|
{
|
||||||
|
if (!Pin2->Connections.Contains(Pin1))
|
||||||
|
{
|
||||||
|
Pin2->Connections.Add(Pin1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//标记数据更新
|
||||||
|
DialogueBeingEdited->Modify();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueAssetEditor::LoadGraphData()
|
||||||
|
{
|
||||||
|
if (DialogueBeingEdited->NodeDatas.Num() == 0)
|
||||||
|
{
|
||||||
|
//空节点,创建默认Root节点
|
||||||
|
DialogueGraph->GetSchema()->CreateDefaultNodesForGraph(*DialogueGraph);
|
||||||
|
UDialogueRuntimeNode* RootNode = NewObject<UDialogueRuntimeNode>();
|
||||||
|
RootNode->NodeType = EDialogueNodeType::Root;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//读取节点信息,创建pin及连线
|
||||||
|
TArray<std::pair<FGuid, FGuid>> Connections;
|
||||||
|
TMap<FGuid, UEdGraphPin*> IdToPinMap;
|
||||||
|
for (UDialogueRuntimeNode* RuntimeNode: DialogueBeingEdited->NodeDatas)
|
||||||
|
{
|
||||||
|
UDialogueGraphNode_Base* EditorNode = nullptr;
|
||||||
|
switch (RuntimeNode->NodeType)
|
||||||
|
{
|
||||||
|
case EDialogueNodeType::Root:
|
||||||
|
EditorNode = NewObject<UDialogueGraphNode_Root>(DialogueGraph);
|
||||||
|
break;
|
||||||
|
case EDialogueNodeType::NPC:
|
||||||
|
EditorNode = NewObject<UDialogueGraphNode_NPC>(DialogueGraph);
|
||||||
|
break;
|
||||||
|
case EDialogueNodeType::Player:
|
||||||
|
EditorNode = NewObject<UDialogueGraphNode_Player>(DialogueGraph);
|
||||||
|
break;
|
||||||
|
default: ;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorNode->CreateNewGuid();
|
||||||
|
EditorNode->SetPostion(RuntimeNode->Position);
|
||||||
|
if (RuntimeNode->NodeData)
|
||||||
|
{
|
||||||
|
EditorNode->SetDialogueNodeData(DuplicateObject(RuntimeNode->NodeData, EditorNode));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorNode->InitializeNodeData();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RuntimeNode->InputPin)
|
||||||
|
{
|
||||||
|
UDialogueRuntimePin* InputPin = RuntimeNode->InputPin;
|
||||||
|
FName Category = TEXT("Inputs");
|
||||||
|
UEdGraphPin* EditorPin = EditorNode->CreatePin((EEdGraphPinDirection)InputPin->Direction, Category, InputPin->PinName);
|
||||||
|
EditorPin->PinId = InputPin->PinId;
|
||||||
|
|
||||||
|
if (InputPin->Connections.Num() > 0)
|
||||||
|
{
|
||||||
|
Connections.Add(std::make_pair(InputPin->PinId, InputPin->Connections[0]->PinId));
|
||||||
|
}
|
||||||
|
IdToPinMap.Add(InputPin->PinId, EditorPin);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UDialogueRuntimePin* RuntimePin : RuntimeNode->OutputPins)
|
||||||
|
{
|
||||||
|
FName Category = TEXT("Outputs");
|
||||||
|
UEdGraphPin* EditorPin = EditorNode->CreatePin((EEdGraphPinDirection)RuntimePin->Direction, Category, RuntimePin->PinName);
|
||||||
|
EditorPin->PinId = RuntimePin->PinId;
|
||||||
|
|
||||||
|
if (RuntimePin->Connections.Num() > 0)
|
||||||
|
{
|
||||||
|
Connections.Add(std::make_pair(RuntimePin->PinId, RuntimePin->Connections[0]->PinId));
|
||||||
|
}
|
||||||
|
IdToPinMap.Add(RuntimePin->PinId, EditorPin);
|
||||||
|
}
|
||||||
|
DialogueGraph->AddNode(EditorNode, true, true);
|
||||||
|
}
|
||||||
|
for (std::pair<FGuid, FGuid> Connection : Connections)
|
||||||
|
{
|
||||||
|
UEdGraphPin* FromPin = IdToPinMap[Connection.first];
|
||||||
|
UEdGraphPin* ToPin = IdToPinMap[Connection.second];
|
||||||
|
FromPin->LinkedTo.Add(ToPin);
|
||||||
|
ToPin->LinkedTo.Add(FromPin);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueAssetEditor::BindGraphCommands()
|
||||||
|
{
|
||||||
|
ToolkitCommands->MapAction(FGenericCommands::Get().Delete,
|
||||||
|
FExecuteAction::CreateSP(this, &FDialogueAssetEditor::DeleteSelectedNodes),
|
||||||
|
FCanExecuteAction::CreateSP(this, &FDialogueAssetEditor::CanDeleteNodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueAssetEditor::DeleteSelectedNodes()
|
||||||
|
{
|
||||||
|
if (!GraphEditor.IsValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const FScopedTransaction Transaction(FGenericCommands::Get().Delete->GetDescription());
|
||||||
|
GraphEditor->GetCurrentGraph()->Modify();
|
||||||
|
|
||||||
|
const FGraphPanelSelectionSet SelectedNodes = GraphEditor->GetSelectedNodes();
|
||||||
|
GraphEditor->ClearSelectionSet();
|
||||||
|
|
||||||
|
for (FGraphPanelSelectionSet::TConstIterator NodeIt(SelectedNodes); NodeIt; ++NodeIt)
|
||||||
|
{
|
||||||
|
|
||||||
|
UEdGraphNode* EdNode = Cast<UEdGraphNode>(*NodeIt);
|
||||||
|
if (EdNode == nullptr || !EdNode->CanUserDeleteNode())
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
if (UDialogueGraphNode_Base* EdNode_Node = Cast<UDialogueGraphNode_Base>(EdNode))
|
||||||
|
{
|
||||||
|
EdNode_Node->Modify();
|
||||||
|
|
||||||
|
const UEdGraphSchema* Schema = EdNode_Node->GetSchema();
|
||||||
|
if (Schema != nullptr)
|
||||||
|
{
|
||||||
|
Schema->BreakNodeLinks(*EdNode_Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
EdNode_Node->DestroyNode();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EdNode->Modify();
|
||||||
|
EdNode->DestroyNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FDialogueAssetEditor::CanDeleteNodes()
|
||||||
|
{
|
||||||
|
if (!GraphEditor.IsValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const FGraphPanelSelectionSet SelectedNodes = GraphEditor->GetSelectedNodes();
|
||||||
|
for (FGraphPanelSelectionSet::TConstIterator SelectedIter(SelectedNodes); SelectedIter; ++SelectedIter)
|
||||||
|
{
|
||||||
|
UEdGraphNode* Node = Cast<UEdGraphNode>(*SelectedIter);
|
||||||
|
if (Node && Node->CanUserDeleteNode())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UDialogueGraphNode_Base* FDialogueAssetEditor::GetSelectedNode(const FGraphPanelSelectionSet& Selection)
|
||||||
|
{
|
||||||
|
for (UObject* Obj : Selection)
|
||||||
|
{
|
||||||
|
if (UDialogueGraphNode_Base* Node = Cast<UDialogueGraphNode_Base>(Obj))
|
||||||
|
{
|
||||||
|
return Node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueAssetEditor::OnNodeDetailViewPropertiesUpdated(const FPropertyChangedEvent& Event)
|
||||||
|
{
|
||||||
|
if (GraphEditor.IsValid())
|
||||||
|
{
|
||||||
|
GraphEditor->NotifyGraphChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "DialogueAssetFactory.h"
|
||||||
|
|
||||||
|
#include "DialogueAsset.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "DialoguePluginEditor"
|
||||||
|
UDialogueAssetFactory::UDialogueAssetFactory(const FObjectInitializer& ObjectInitializer)
|
||||||
|
{
|
||||||
|
SupportedClass = UDialogueAsset::StaticClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
UObject* UDialogueAssetFactory::FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags,
|
||||||
|
UObject* Context, FFeedbackContext* Warn, FName CallingContext)
|
||||||
|
{
|
||||||
|
UDialogueAsset* NewObjectAsset = NewObject<UDialogueAsset>(InParent, InClass, InName, Flags | RF_Transactional);
|
||||||
|
return NewObjectAsset;
|
||||||
|
}
|
||||||
|
|
||||||
|
FString UDialogueAssetFactory::GetDefaultNewAssetName() const
|
||||||
|
{
|
||||||
|
return FString(TEXT("NewDialogue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UDialogueAssetFactory::ShouldShowInNewMenu() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FText UDialogueAssetFactory::GetDisplayName() const
|
||||||
|
{
|
||||||
|
return LOCTEXT("DialogueName", "Dialogue");
|
||||||
|
}
|
||||||
|
#undef LOCATEXT_NAMESPACE
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#include "DialogueDetailsTabSummoner.h"
|
||||||
|
#include "DialogueAssetEditor.h"
|
||||||
|
#include "PropertyEditorModule.h"
|
||||||
|
#include "IDetailsView.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "DialogueDetailsTabSummoner"
|
||||||
|
|
||||||
|
const FName DialogueDetailsTabId = FName(TEXT("DialogueDetailsTabId"));
|
||||||
|
|
||||||
|
FDialogueDetailsTabSummoner::FDialogueDetailsTabSummoner(TSharedPtr<FDialogueAssetEditor> InDialogueEditor)
|
||||||
|
: FWorkflowTabFactory(DialogueDetailsTabId, InDialogueEditor)
|
||||||
|
{
|
||||||
|
DialogueEditor = InDialogueEditor;
|
||||||
|
TabLabel = LOCTEXT("DialogueDetailsTabLabel", "Details");
|
||||||
|
ViewMenuDescription = LOCTEXT("DialogueDetails_ViewMenu_Desc", "Details");
|
||||||
|
ViewMenuTooltip = LOCTEXT("DialogueDetails_ViewMenu_ToolTip", "Show the Details Panel");
|
||||||
|
}
|
||||||
|
|
||||||
|
TSharedRef<SWidget> FDialogueDetailsTabSummoner::CreateTabBody(const FWorkflowTabSpawnInfo& Info) const
|
||||||
|
{
|
||||||
|
TSharedPtr<FDialogueAssetEditor> Editor = DialogueEditor.Pin();
|
||||||
|
FPropertyEditorModule& PropertyEditorModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>(TEXT("PropertyEditor"));
|
||||||
|
|
||||||
|
FDetailsViewArgs DetailsViewArgs;
|
||||||
|
DetailsViewArgs.bAllowSearch = false;
|
||||||
|
DetailsViewArgs.bHideSelectionTip = true;
|
||||||
|
DetailsViewArgs.bLockable = false;
|
||||||
|
DetailsViewArgs.bSearchInitialKeyFocus = true;
|
||||||
|
DetailsViewArgs.bUpdatesFromSelection = false;
|
||||||
|
DetailsViewArgs.NotifyHook = nullptr;
|
||||||
|
DetailsViewArgs.bShowOptions = true;
|
||||||
|
DetailsViewArgs.bShowModifiedPropertiesOption = false;
|
||||||
|
DetailsViewArgs.bShowScrollBar = false;
|
||||||
|
|
||||||
|
TSharedPtr<IDetailsView> DetailsView = PropertyEditorModule.CreateDetailView(DetailsViewArgs);
|
||||||
|
DetailsView->SetObject(nullptr);
|
||||||
|
Editor->SetDetailsView(DetailsView);
|
||||||
|
|
||||||
|
return SNew(SVerticalBox)
|
||||||
|
+ SVerticalBox::Slot()
|
||||||
|
.FillHeight(1.0f)
|
||||||
|
.HAlign(HAlign_Fill)
|
||||||
|
[
|
||||||
|
DetailsView.ToSharedRef()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
FText FDialogueDetailsTabSummoner::GetTabToolTipText(const FWorkflowTabSpawnInfo& Info) const
|
||||||
|
{
|
||||||
|
return LOCTEXT("DialogueDetailsTooltip", "The details panel for selected nodes");
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
#include "DialogueEditor.h"
|
||||||
|
|
||||||
|
#include "AssetToolsModule.h"
|
||||||
|
#include "DialogueEditorStyle.h"
|
||||||
|
#include "DialogueSettings.h"
|
||||||
|
#include "FDialogueAssetTypeActions.h"
|
||||||
|
#include "IAssetTools.h"
|
||||||
|
#include "ISettingsModule.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "FDialogueEditorModule"
|
||||||
|
|
||||||
|
void FDialogueEditorModule::StartupModule()
|
||||||
|
{
|
||||||
|
//添加需要用到的图标资源
|
||||||
|
FDialogueEditorStyle::Initialize();
|
||||||
|
//添加对话相关属性设置
|
||||||
|
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
|
||||||
|
{
|
||||||
|
SettingsModule->RegisterSettings("Project", "Plugins", "Dialogue Plugin",
|
||||||
|
LOCTEXT("SettinsName", "Dialogue Plugin"),
|
||||||
|
LOCTEXT("SettingsDes", "Configue Dialogue Plugin"),
|
||||||
|
GetMutableDefault<UDialogueSettings>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//添加对话资源创建菜单
|
||||||
|
IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get();
|
||||||
|
EAssetTypeCategories::Type DialogueAssetCategory = AssetTools.RegisterAdvancedAssetCategory(FName(TEXT("Dialogue")), LOCTEXT("Dialogue", "Dialogue"));
|
||||||
|
TSharedRef<FAssetTypeActions_Base> DialogueAssetTypeActions = MakeShareable(new FDialogueAssetTypeActions(DialogueAssetCategory));
|
||||||
|
CreatedAssetTypeActions.Add(DialogueAssetTypeActions);
|
||||||
|
AssetTools.RegisterAssetTypeActions(DialogueAssetTypeActions);
|
||||||
|
|
||||||
|
// //添加自定义的属性窗口
|
||||||
|
// FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
|
||||||
|
// PropertyModule.RegisterCustomClassLayout("DialogueAsset", FOnGetDetailCustomizationInstance::CreateStatic(&FDialogueAssetEditorDetails::MakeInstance));
|
||||||
|
// PropertyModule.NotifyCustomizationModuleChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueEditorModule::ShutdownModule()
|
||||||
|
{
|
||||||
|
//注销图标资源
|
||||||
|
FDialogueEditorStyle::Shutdown();
|
||||||
|
//注销setting
|
||||||
|
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
|
||||||
|
{
|
||||||
|
SettingsModule->UnregisterSettings("Project", "Plugins", "Dialogue Plugin");
|
||||||
|
}
|
||||||
|
//注销typeaction
|
||||||
|
if (FModuleManager::Get().IsModuleLoaded("AssetTools"))
|
||||||
|
{
|
||||||
|
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
|
||||||
|
IAssetTools& AssetTools = AssetToolsModule.Get();
|
||||||
|
for (auto Action : CreatedAssetTypeActions)
|
||||||
|
{
|
||||||
|
|
||||||
|
AssetTools.UnregisterAssetTypeActions(Action.ToSharedRef());
|
||||||
|
}
|
||||||
|
CreatedAssetTypeActions.Empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
|
|
||||||
|
IMPLEMENT_MODULE(FDialogueEditorModule, DialogueEditor)
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#include "DialogueEditorMode.h"
|
||||||
|
#include "DialogueAssetEditor.h"
|
||||||
|
#include "DialogueGraphTabSummoner.h"
|
||||||
|
#include "DialogueDetailsTabSummoner.h"
|
||||||
|
|
||||||
|
FDialogueEditorMode::FDialogueEditorMode(TSharedPtr<FDialogueAssetEditor> InDialogueEditor)
|
||||||
|
: FApplicationMode(TEXT("DialogueEditorMode"))
|
||||||
|
{
|
||||||
|
DialogueEditor = InDialogueEditor;
|
||||||
|
|
||||||
|
// 注册Tab工厂
|
||||||
|
TabFactories.RegisterFactory(MakeShared<FDialogueGraphTabSummoner>(InDialogueEditor));
|
||||||
|
TabFactories.RegisterFactory(MakeShared<FDialogueDetailsTabSummoner>(InDialogueEditor));
|
||||||
|
|
||||||
|
// 定义布局
|
||||||
|
TabLayout = FTabManager::NewLayout("Standalone_DialogueEditor_Layout_v1")
|
||||||
|
->AddArea
|
||||||
|
(
|
||||||
|
FTabManager::NewPrimaryArea()
|
||||||
|
->SetOrientation(Orient_Vertical)
|
||||||
|
->Split
|
||||||
|
(
|
||||||
|
FTabManager::NewSplitter()
|
||||||
|
->SetOrientation(Orient_Horizontal)
|
||||||
|
->Split
|
||||||
|
(
|
||||||
|
FTabManager::NewStack()
|
||||||
|
->SetSizeCoefficient(0.7f)
|
||||||
|
->AddTab(FName(TEXT("DialogueGraphTabId")), ETabState::OpenedTab)
|
||||||
|
)
|
||||||
|
->Split
|
||||||
|
(
|
||||||
|
FTabManager::NewStack()
|
||||||
|
->SetSizeCoefficient(0.3f)
|
||||||
|
->AddTab(FName(TEXT("DialogueDetailsTabId")), ETabState::OpenedTab)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueEditorMode::RegisterTabFactories(TSharedPtr<FTabManager> InTabManager)
|
||||||
|
{
|
||||||
|
TSharedPtr<FDialogueAssetEditor> Editor = DialogueEditor.Pin();
|
||||||
|
Editor->PushTabFactories(TabFactories);
|
||||||
|
FApplicationMode::RegisterTabFactories(InTabManager);
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
#include "DialogueEditorStyle.h"
|
||||||
|
|
||||||
|
#include "Styling/SlateStyle.h"
|
||||||
|
#include "Styling/SlateStyleRegistry.h"
|
||||||
|
#include "Interfaces/IPluginManager.h"
|
||||||
|
#include "Styling/SlateStyleRegistry.h"
|
||||||
|
|
||||||
|
TSharedPtr< FSlateStyleSet > FDialogueEditorStyle::StyleSet = nullptr;
|
||||||
|
TSharedPtr< ISlateStyle > FDialogueEditorStyle::Get() { return StyleSet; }
|
||||||
|
|
||||||
|
void FDialogueEditorStyle::Initialize()
|
||||||
|
{
|
||||||
|
if (StyleSet.IsValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StyleSet = MakeShareable(new FSlateStyleSet(FName(TEXT("DialogueEditorStyle"))));
|
||||||
|
FString ResourceDir = IPluginManager::Get().FindPlugin("Dialogue")->GetBaseDir() / TEXT("Resources");
|
||||||
|
//加载图标相关资源
|
||||||
|
StyleSet->Set("PlayerNodeStyle", new FSlateBoxBrush(ResourceDir/"playerNode.png", FMargin(5.f / 138.f, 5.f / 56.f, 5.f / 138.f, 5.f / 56.f))); // left top right bottom
|
||||||
|
StyleSet->Set("NpcNodeStyle", new FSlateBoxBrush(ResourceDir/"npcNode.png", FMargin(5.f / 138.f, 5.f / 56.f, 5.f / 138.f, 5.f / 56.f)));
|
||||||
|
StyleSet->Set("StartNodeStyle", new FSlateBoxBrush(ResourceDir/"startNode.png", FMargin(5.f / 138.f, 5.f / 56.f, 5.f / 138.f, 5.f / 56.f)));
|
||||||
|
|
||||||
|
StyleSet->Set("EventIcon", new FSlateImageBrush(ResourceDir/"event.png", FVector2D(14, 16)));
|
||||||
|
StyleSet->Set("ConditionIcon", new FSlateImageBrush(ResourceDir/"condition.png", FVector2D(16, 16)));
|
||||||
|
StyleSet->Set("VoiceIcon", new FSlateImageBrush(ResourceDir/"sound.png", FVector2D(17, 16)));
|
||||||
|
|
||||||
|
StyleSet->Set(FName(TEXT("ClassThumbnail.DialogueAsset")), new FSlateImageBrush(ResourceDir/"dialogue_64.png", FVector2D(64, 64)));
|
||||||
|
StyleSet->Set(FName(TEXT("ClassIcon.DialogueAsset")), new FSlateImageBrush(ResourceDir/"dialogue_16.png", FVector2D(16, 16)));
|
||||||
|
|
||||||
|
FSlateStyleRegistry::RegisterSlateStyle(*StyleSet.Get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueEditorStyle::Shutdown()
|
||||||
|
{
|
||||||
|
if (StyleSet.IsValid())
|
||||||
|
{
|
||||||
|
FSlateStyleRegistry::UnRegisterSlateStyle(*StyleSet.Get());
|
||||||
|
StyleSet.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#include "DialogueGraph.h"
|
||||||
|
|
||||||
|
UDialogueGraph::UDialogueGraph()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDialogueGraph::AddNode(UEdGraphNode* NodeToAdd, bool bUserAction, bool bSelectNewNode)
|
||||||
|
{
|
||||||
|
Super::AddNode(NodeToAdd, bUserAction, bSelectNewNode);
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "DialogueGraphPanelNodeFactory.h"
|
||||||
|
|
||||||
|
#include "Node//DialogueGraphNode_NPC.h"
|
||||||
|
#include "Node/DialogueGraphNode_Player.h"
|
||||||
|
#include "Widget/DialogueGraphNode.h"
|
||||||
|
|
||||||
|
|
||||||
|
TSharedPtr<SGraphNode> FDialogueGraphPanelNodeFactory::CreateNode(class UEdGraphNode* InNode) const
|
||||||
|
{
|
||||||
|
if (UDialogueGraphNode_NPC* NPCNode = Cast<UDialogueGraphNode_NPC>(InNode))
|
||||||
|
return SNew(SDialogueGraphNode, NPCNode);
|
||||||
|
|
||||||
|
if (UDialogueGraphNode_Player* PlayerNode = Cast<UDialogueGraphNode_Player>(InNode))
|
||||||
|
return SNew(SDialogueGraphNode, PlayerNode);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "DialogueGraphPanelPinFactory.h"
|
||||||
|
|
||||||
|
#include "Node/DialogueGraphNode_Base.h"
|
||||||
|
#include "Node/DialogueGraphNode_NPC.h"
|
||||||
|
#include "Node/DialogueGraphNode_Player.h"
|
||||||
|
#include "Widget/DialogueGraphPin.h"
|
||||||
|
|
||||||
|
|
||||||
|
TSharedPtr<class SGraphPin> FDialogueGraphPanelPinFactory::CreatePin(class UEdGraphPin* InPin) const
|
||||||
|
{
|
||||||
|
UEdGraphNode* ParentNode = InPin->GetOwningNode();
|
||||||
|
if (ParentNode->IsA(UDialogueGraphNode_NPC::StaticClass())
|
||||||
|
|| ParentNode->IsA(UDialogueGraphNode_Player::StaticClass()))
|
||||||
|
{
|
||||||
|
return SNew(SDialogueGraphPin, InPin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return SNew(SDialogueNoneGraphPin, InPin);
|
||||||
|
}
|
||||||
|
// For response nodes, return horizontal box with textblock and pin
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#include "DialogueGraphSchema.h"
|
||||||
|
#include "Node/DialogueGraphNode_Base.h"
|
||||||
|
#include "Node/DialogueGraphNode_NPC.h"
|
||||||
|
#include "Node/DialogueGraphNode_Player.h"
|
||||||
|
#include "Node/DialogueGraphNode_Root.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "DialogueGraphSchema"
|
||||||
|
|
||||||
|
UEdGraphNode* FDialogueGraphSchemaAction_NewNode::PerformAction(UEdGraph* ParentGraph, UEdGraphPin* FromPin, const FVector2D Location, bool bSelectNewNode)
|
||||||
|
{
|
||||||
|
UDialogueGraphNode_Base* NewNode = NewObject<UDialogueGraphNode_Base>(ParentGraph, ClassTemplate);
|
||||||
|
NewNode->CreateNewGuid();
|
||||||
|
NewNode->SetPostion(Location);
|
||||||
|
NewNode->InitializeNodeData();
|
||||||
|
NewNode->AllocateDefaultPins();
|
||||||
|
|
||||||
|
ParentGraph->Modify();
|
||||||
|
ParentGraph->AddNode(NewNode, true, bSelectNewNode);
|
||||||
|
|
||||||
|
// 如果从某个Pin拖拽创建,自动连接
|
||||||
|
if (FromPin && NewNode->Pins.Num() > 0)
|
||||||
|
{
|
||||||
|
for (UEdGraphPin* Pin : NewNode->Pins)
|
||||||
|
{
|
||||||
|
if (Pin->Direction != FromPin->Direction)
|
||||||
|
{
|
||||||
|
GetDefault<UDialogueGraphSchema>()->TryCreateConnection(FromPin, Pin);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDialogueGraphSchema::CreateDefaultNodesForGraph(UEdGraph& Graph) const
|
||||||
|
{
|
||||||
|
FGraphNodeCreator<UDialogueGraphNode_Root> NodeCreator(Graph);
|
||||||
|
UDialogueGraphNode_Root* MyNode = NodeCreator.CreateNode(true, UDialogueGraphNode_Root::StaticClass());
|
||||||
|
NodeCreator.Finalize();
|
||||||
|
SetNodeMetaData(MyNode, FNodeMetadata::DefaultGraphNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDialogueGraphSchema::GetGraphContextActions(FGraphContextMenuBuilder& ContextMenuBuilder) const
|
||||||
|
{
|
||||||
|
// 添加npc对话节点
|
||||||
|
TSharedPtr<FDialogueGraphSchemaAction_NewNode> NPCNodeAction = MakeShareable(new FDialogueGraphSchemaAction_NewNode(
|
||||||
|
UDialogueGraphNode_NPC::StaticClass(),
|
||||||
|
LOCTEXT("DialogueNode_NPC_Category", "NPC Dialogue"),
|
||||||
|
LOCTEXT("DialogueNode_NPC_Desc", "NPC Dialogue Node"),
|
||||||
|
LOCTEXT("DialogueNode_NPC_Tooltip", "Create a npc dialogue node")
|
||||||
|
));
|
||||||
|
ContextMenuBuilder.AddAction(NPCNodeAction);
|
||||||
|
// 添加npc对话节点
|
||||||
|
TSharedPtr<FDialogueGraphSchemaAction_NewNode> PlayerNodeAction = MakeShareable(new FDialogueGraphSchemaAction_NewNode(
|
||||||
|
UDialogueGraphNode_Player::StaticClass(),
|
||||||
|
LOCTEXT("DialogueNode_Player_Category", "Player Dialogue"),
|
||||||
|
LOCTEXT("DialogueNode_Player_Desc", "Player Dialogue Node"),
|
||||||
|
LOCTEXT("DialogueNode_Player_Tooltip", "Create a Player dialogue node")
|
||||||
|
));
|
||||||
|
ContextMenuBuilder.AddAction(PlayerNodeAction);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const FPinConnectionResponse UDialogueGraphSchema::CanCreateConnection(const UEdGraphPin* A, const UEdGraphPin* B) const
|
||||||
|
{
|
||||||
|
// 不能连接自己
|
||||||
|
if (A->GetOwningNode() == B->GetOwningNode())
|
||||||
|
{
|
||||||
|
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("ConnectionSameNode", "Cannot connect to self"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 必须一个输入一个输出
|
||||||
|
if (A->Direction == B->Direction)
|
||||||
|
{
|
||||||
|
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("ConnectionSameDirection", "Must connect input to output"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return FPinConnectionResponse(CONNECT_RESPONSE_MAKE, TEXT(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#include "DialogueGraphTabSummoner.h"
|
||||||
|
#include "DialogueAssetEditor.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "DialogueGraphTabSummoner"
|
||||||
|
|
||||||
|
const FName DialogueGraphTabId = FName(TEXT("DialogueGraphTabId"));
|
||||||
|
|
||||||
|
FDialogueGraphTabSummoner::FDialogueGraphTabSummoner(TSharedPtr<FDialogueAssetEditor> InDialogueEditor)
|
||||||
|
: FWorkflowTabFactory(DialogueGraphTabId, InDialogueEditor)
|
||||||
|
{
|
||||||
|
DialogueEditor = InDialogueEditor;
|
||||||
|
TabLabel = LOCTEXT("DialogueGraphTabLabel", "Dialogue Graph");
|
||||||
|
ViewMenuDescription = LOCTEXT("DialogueGraph_ViewMenu_Desc", "Dialogue Graph");
|
||||||
|
ViewMenuTooltip = LOCTEXT("DialogueGraph_ViewMenu_ToolTip", "Show the Dialogue Graph");
|
||||||
|
}
|
||||||
|
|
||||||
|
TSharedRef<SWidget> FDialogueGraphTabSummoner::CreateTabBody(const FWorkflowTabSpawnInfo& Info) const
|
||||||
|
{
|
||||||
|
TSharedPtr<FDialogueAssetEditor> Editor = DialogueEditor.Pin();
|
||||||
|
|
||||||
|
SGraphEditor::FGraphEditorEvents GraphEvents;
|
||||||
|
GraphEvents.OnSelectionChanged.BindSP(Editor.Get(), &FDialogueAssetEditor::OnGraphSelectionChanged);
|
||||||
|
|
||||||
|
TSharedPtr<SGraphEditor> GraphEditor =
|
||||||
|
SNew(SGraphEditor)
|
||||||
|
.IsEditable(true)
|
||||||
|
.GraphEvents(GraphEvents)
|
||||||
|
.GraphToEdit(Editor->GetDialogueGraph());
|
||||||
|
|
||||||
|
Editor->SetGraphEditor(GraphEditor);
|
||||||
|
|
||||||
|
return GraphEditor.ToSharedRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
FText FDialogueGraphTabSummoner::GetTabToolTipText(const FWorkflowTabSpawnInfo& Info) const
|
||||||
|
{
|
||||||
|
return LOCTEXT("DialogueGraphTooltip", "The dialogue graph editor");
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "FDialogueAssetTypeActions.h"
|
||||||
|
|
||||||
|
#include "DialogueAsset.h"
|
||||||
|
#include "DialogueAssetEditor.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "AssetTypeActions"
|
||||||
|
|
||||||
|
FDialogueAssetTypeActions::FDialogueAssetTypeActions(uint32 InAssetCategory)
|
||||||
|
: MyAssetCategory(InAssetCategory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FText FDialogueAssetTypeActions::GetName() const
|
||||||
|
{
|
||||||
|
return LOCTEXT("DialogueAssetTypeActionsName", "Dialogue");
|
||||||
|
}
|
||||||
|
|
||||||
|
FColor FDialogueAssetTypeActions::GetTypeColor() const
|
||||||
|
{
|
||||||
|
return FColor(255, 55, 220);
|
||||||
|
}
|
||||||
|
|
||||||
|
UClass* FDialogueAssetTypeActions::GetSupportedClass() const
|
||||||
|
{
|
||||||
|
return UDialogueAsset::StaticClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDialogueAssetTypeActions::OpenAssetEditor(const TArray<UObject*>& InObjects,
|
||||||
|
TSharedPtr<IToolkitHost> EditWithinLevelEditor)
|
||||||
|
{
|
||||||
|
EToolkitMode::Type Mode = EditWithinLevelEditor.IsValid() ? EToolkitMode::WorldCentric : EToolkitMode::Standalone;
|
||||||
|
|
||||||
|
for (auto ObjIt = InObjects.CreateConstIterator(); ObjIt; ++ObjIt)
|
||||||
|
{
|
||||||
|
if (UDialogueAsset* DialogueAsset = Cast<UDialogueAsset>(*ObjIt))
|
||||||
|
{
|
||||||
|
TSharedRef<FDialogueAssetEditor> Editor = MakeShareable(new FDialogueAssetEditor());
|
||||||
|
Editor->InitDialogueEditor(Mode, EditWithinLevelEditor, DialogueAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//FAssetTypeActions_Base::OpenAssetEditor(InObjects, EditWithinLevelEditor);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 FDialogueAssetTypeActions::GetCategories()
|
||||||
|
{
|
||||||
|
return MyAssetCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#include "Node/DialogueGraphNode_Base.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "DialogueGraphNode"
|
||||||
|
|
||||||
|
UDialogueGraphNode_Base::UDialogueGraphNode_Base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDialogueGraphNode_Base::AllocateDefaultPins()
|
||||||
|
{
|
||||||
|
DefaultInputPin = CreatePin(EGPD_Input, TEXT("PinCategory_Default"), TEXT("In"));
|
||||||
|
CreatePin(EGPD_Output, TEXT("PinCategory_Default"), TEXT("Out"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDialogueGraphNode_Base::SetPostion(FVector2D InPos)
|
||||||
|
{
|
||||||
|
NodePosX = InPos.X;
|
||||||
|
NodePosY = InPos.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDialogueGraphNode_Base::InitializeNodeData()
|
||||||
|
{
|
||||||
|
NodeData = NewObject<UDialogueNodeData_Base>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDialogueGraphNode_Base::OnPropertiesChanged()
|
||||||
|
{
|
||||||
|
GetGraph()->NotifyNodeChanged(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
|
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "Node/DialogueGraphNode_NPC.h"
|
||||||
|
|
||||||
|
|
||||||
|
UDialogueGraphNode_NPC::UDialogueGraphNode_NPC()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
#include "Node/DialogueGraphNode_Player.h"
|
||||||
|
|
||||||
|
UDialogueGraphNode_Player::UDialogueGraphNode_Player()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "Node/DialogueGraphNode_Root.h"
|
||||||
|
|
||||||
|
void UDialogueGraphNode_Root::AllocateDefaultPins()
|
||||||
|
{
|
||||||
|
CreatePin(EGPD_Output, TEXT("PinCategory_Default"), TEXT("In"));
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "Widget/DialogueGraphNode.h"
|
||||||
|
|
||||||
|
|
||||||
|
void SDialogueGraphNode::Construct(const FArguments& InArgs, UDialogueGraphNode_Base* InNode)
|
||||||
|
{
|
||||||
|
GraphNode = InNode;
|
||||||
|
UpdateGraphNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
FText SDialogueGraphNode::GetDialogueText() const
|
||||||
|
{
|
||||||
|
UDialogueGraphNode_Base* DialogueNode = Cast<UDialogueGraphNode_Base>(GraphNode);
|
||||||
|
return DialogueNode->GetDialogueNodeData()->Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSharedRef<SWidget> SDialogueGraphNode::CreateNodeContentArea()
|
||||||
|
{
|
||||||
|
// NODE CONTENT AREA
|
||||||
|
return SNew(SBorder)
|
||||||
|
.BorderImage( FAppStyle::GetBrush("NoBorder") )
|
||||||
|
.HAlign(HAlign_Fill)
|
||||||
|
.VAlign(VAlign_Fill)
|
||||||
|
.Padding( FMargin(0,3) )
|
||||||
|
[
|
||||||
|
SNew(SHorizontalBox)
|
||||||
|
+SHorizontalBox::Slot()
|
||||||
|
.HAlign(HAlign_Left)
|
||||||
|
.FillWidth(1.0f)
|
||||||
|
[
|
||||||
|
// LEFT
|
||||||
|
SAssignNew(LeftNodeBox, SVerticalBox)
|
||||||
|
]
|
||||||
|
+SHorizontalBox::Slot()
|
||||||
|
.AutoWidth()
|
||||||
|
.HAlign(HAlign_Center)
|
||||||
|
.Padding(10.0f, 5.0f)
|
||||||
|
[
|
||||||
|
SNew(SBorder)
|
||||||
|
.BorderBackgroundColor(FSlateColor(FLinearColor::Gray))
|
||||||
|
.Padding(10.0f)
|
||||||
|
.Content()
|
||||||
|
[
|
||||||
|
SAssignNew(DialogueText, STextBlock)
|
||||||
|
.MinDesiredWidth(260.0f)
|
||||||
|
.Text(this, &SDialogueGraphNode::GetDialogueText)
|
||||||
|
.WrapTextAt(250.0f)
|
||||||
|
]
|
||||||
|
]
|
||||||
|
+SHorizontalBox::Slot()
|
||||||
|
.AutoWidth()
|
||||||
|
.HAlign(HAlign_Right)
|
||||||
|
[
|
||||||
|
// RIGHT
|
||||||
|
SAssignNew(RightNodeBox, SVerticalBox)
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "Widget/DialogueGraphPin.h"
|
||||||
|
|
||||||
|
#include "Node/DialogueGraphNode_Base.h"
|
||||||
|
|
||||||
|
|
||||||
|
void SDialogueGraphPin::Construct(const FArguments& InArgs, UEdGraphPin* InPin)
|
||||||
|
{
|
||||||
|
SGraphPin::Construct(SGraphPin::FArguments(), InPin);
|
||||||
|
// FullPinHorizontalRowWidget.Pin()
|
||||||
|
// ->InsertSlot(0)
|
||||||
|
// [
|
||||||
|
// SNew(SBorder)
|
||||||
|
// .BorderBackgroundColor(FSlateColor(FLinearColor::Gray))
|
||||||
|
// .Padding(10.0f)
|
||||||
|
// .Content()
|
||||||
|
// [
|
||||||
|
// SAssignNew(DialogueText, STextBlock)
|
||||||
|
// .MinDesiredWidth(260.0f)
|
||||||
|
// .WrapTextAt(250.0f)
|
||||||
|
// .Text(this, &SDialogueGraphPin::GetDialogueText)
|
||||||
|
// ]
|
||||||
|
// ];
|
||||||
|
}
|
||||||
|
|
||||||
|
FText SDialogueGraphPin::GetDialogueText() const
|
||||||
|
{
|
||||||
|
UEdGraphPin* ParentPin = GetPinObj();
|
||||||
|
if (UDialogueGraphNode_Base* ResponseNode = Cast<UDialogueGraphNode_Base>(ParentPin->GetOwningNode()))
|
||||||
|
{
|
||||||
|
return ResponseNode->GetDialogueNodeData()->Text;
|
||||||
|
}
|
||||||
|
return FText();
|
||||||
|
}
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "DialogueAsset.h"
|
||||||
|
#include "GraphEditor.h"
|
||||||
|
#include "WorkflowOrientedApp/WorkflowCentricApplication.h"
|
||||||
|
|
||||||
|
class UDialogueGraph;
|
||||||
|
class IDetailsView;
|
||||||
|
class UDialogueGraphNode_Base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话编辑器工具包
|
||||||
|
*/
|
||||||
|
class DIALOGUEEDITOR_API FDialogueAssetEditor : public FWorkflowCentricApplication, public FEditorUndoClient, public FNotifyHook
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** IAssetEditorToolkit interface */
|
||||||
|
virtual FName GetToolkitFName() const override { return FName("DialogueEditor"); }
|
||||||
|
virtual FText GetBaseToolkitName() const override;
|
||||||
|
virtual FString GetWorldCentricTabPrefix() const override { return TEXT("DialogueEditor"); }
|
||||||
|
virtual FLinearColor GetWorldCentricTabColorScale() const override { return FLinearColor::White; }
|
||||||
|
|
||||||
|
virtual void OnClose() override;
|
||||||
|
/** IAssetEditorToolkit interface */
|
||||||
|
|
||||||
|
FDialogueAssetEditor();
|
||||||
|
virtual ~FDialogueAssetEditor();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void InitDialogueEditor(const EToolkitMode::Type Mode, const TSharedPtr<IToolkitHost>& InitToolkitHost, TObjectPtr<class UDialogueAsset> InitDialogueAsset);
|
||||||
|
|
||||||
|
// 获取图表
|
||||||
|
UEdGraph* GetDialogueGraph() const { return DialogueGraph; }
|
||||||
|
|
||||||
|
// 设置图表编辑器
|
||||||
|
void SetGraphEditor(TSharedPtr<SGraphEditor> InGraphEditor) { GraphEditor = InGraphEditor; }
|
||||||
|
|
||||||
|
// 设置细节面板
|
||||||
|
void SetDetailsView(TSharedPtr<IDetailsView> InDetailsView);
|
||||||
|
|
||||||
|
// 图表选择改变回调,传递属性页需要显示的内容
|
||||||
|
void OnGraphSelectionChanged(const FGraphPanelSelectionSet& Selection);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void SaveGraphData();
|
||||||
|
void LoadGraphData();
|
||||||
|
protected:
|
||||||
|
TObjectPtr<UDialogueAsset> DialogueBeingEdited;
|
||||||
|
|
||||||
|
// 图表对象
|
||||||
|
UEdGraph* DialogueGraph;
|
||||||
|
|
||||||
|
// 图表编辑器Widget
|
||||||
|
TSharedPtr<SGraphEditor> GraphEditor;
|
||||||
|
|
||||||
|
// 细节面板
|
||||||
|
TSharedPtr<IDetailsView> DetailsView;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 绑定图表命令
|
||||||
|
void BindGraphCommands();
|
||||||
|
|
||||||
|
// 删除选中节点
|
||||||
|
void DeleteSelectedNodes();
|
||||||
|
bool CanDeleteNodes();
|
||||||
|
|
||||||
|
// 获取选中节点
|
||||||
|
UDialogueGraphNode_Base* GetSelectedNode(const FGraphPanelSelectionSet& Selection);
|
||||||
|
|
||||||
|
// 属性更新回调
|
||||||
|
void OnNodeDetailViewPropertiesUpdated(const FPropertyChangedEvent& Event);
|
||||||
|
};
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Factories/Factory.h"
|
||||||
|
#include "DialogueAssetFactory.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class DIALOGUEEDITOR_API UDialogueAssetFactory : public UFactory
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
UDialogueAssetFactory(const FObjectInitializer& ObjectInitializer);
|
||||||
|
|
||||||
|
virtual UObject* FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn, FName CallingContext) override;
|
||||||
|
virtual FText GetDisplayName() const override;
|
||||||
|
virtual FString GetDefaultNewAssetName() const override;
|
||||||
|
virtual bool ShouldShowInNewMenu() const override;
|
||||||
|
};
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "WorkflowOrientedApp/WorkflowTabFactory.h"
|
||||||
|
|
||||||
|
class FDialogueAssetEditor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 细节面板Tab工厂
|
||||||
|
*/
|
||||||
|
class FDialogueDetailsTabSummoner : public FWorkflowTabFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FDialogueDetailsTabSummoner(TSharedPtr<FDialogueAssetEditor> InDialogueEditor);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TWeakPtr<FDialogueAssetEditor> DialogueEditor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** FWorkflowTabFactory Interface */
|
||||||
|
virtual TSharedRef<SWidget> CreateTabBody(const FWorkflowTabSpawnInfo& Info) const override;
|
||||||
|
virtual FText GetTabToolTipText(const FWorkflowTabSpawnInfo& Info) const override;
|
||||||
|
};
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Modules/ModuleManager.h"
|
||||||
|
|
||||||
|
class FDialogueEditorModule : public IModuleInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void StartupModule() override;
|
||||||
|
virtual void ShutdownModule() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TArray<TSharedPtr<class FAssetTypeActions_Base>>CreatedAssetTypeActions;
|
||||||
|
};
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "WorkflowOrientedApp/ApplicationMode.h"
|
||||||
|
#include "WorkflowOrientedApp/WorkflowTabManager.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话编辑器模式
|
||||||
|
*/
|
||||||
|
class FDialogueEditorMode : public FApplicationMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FDialogueEditorMode(TSharedPtr<class FDialogueAssetEditor> InDialogueEditor);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TWeakPtr<class FDialogueAssetEditor> DialogueEditor;
|
||||||
|
FWorkflowAllowedTabSet TabFactories;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** FApplicationMode */
|
||||||
|
virtual void RegisterTabFactories(TSharedPtr<FTabManager> InTabManager) override;
|
||||||
|
|
||||||
|
};
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class FDialogueEditorStyle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void Initialize();
|
||||||
|
static void Shutdown();
|
||||||
|
|
||||||
|
static TSharedPtr< class ISlateStyle > Get();
|
||||||
|
private:
|
||||||
|
static TSharedPtr<class FSlateStyleSet> StyleSet;
|
||||||
|
};
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "EdGraph/EdGraph.h"
|
||||||
|
#include "DialogueGraph.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话图表类
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class DIALOGUEEDITOR_API UDialogueGraph : public UEdGraph
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UDialogueGraph();
|
||||||
|
/** UEdGraph interface */
|
||||||
|
virtual void AddNode(UEdGraphNode* NodeToAdd, bool bUserAction, bool bSelectNewNode) override;
|
||||||
|
};
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "EdGraphUtilities.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class DIALOGUEEDITOR_API FDialogueGraphPanelNodeFactory: public FGraphPanelNodeFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual TSharedPtr<class SGraphNode> CreateNode(class UEdGraphNode* Node) const override;
|
||||||
|
};
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "DialogueGraphPanelNodeFactory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class DIALOGUEEDITOR_API FDialogueGraphPanelPinFactory: public FGraphPanelPinFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual TSharedPtr<class SGraphPin> CreatePin(class UEdGraphPin* InPin) const override;
|
||||||
|
};
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "EdGraph/EdGraphSchema.h"
|
||||||
|
#include "DialogueGraphSchema.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建节点的Action
|
||||||
|
*/
|
||||||
|
USTRUCT()
|
||||||
|
struct FDialogueGraphSchemaAction_NewNode : public FEdGraphSchemaAction
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
FDialogueGraphSchemaAction_NewNode() : FEdGraphSchemaAction() {}
|
||||||
|
|
||||||
|
FDialogueGraphSchemaAction_NewNode(UClass* InClassTemplate, FText InNodeCategory, FText InMenuDesc, FText InToolTip)
|
||||||
|
: FEdGraphSchemaAction(InNodeCategory, InMenuDesc, InToolTip, 0), ClassTemplate(InClassTemplate) {}
|
||||||
|
|
||||||
|
virtual UEdGraphNode* PerformAction(UEdGraph* ParentGraph, UEdGraphPin* FromPin, const FVector2D Location, bool bSelectNewNode = true) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
UClass* ClassTemplate = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话图表规则
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class DIALOGUEEDITOR_API UDialogueGraphSchema : public UEdGraphSchema
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** UEdGraphSchema */
|
||||||
|
virtual void CreateDefaultNodesForGraph(UEdGraph& Graph) const override;
|
||||||
|
// 右键菜单创建节点
|
||||||
|
virtual void GetGraphContextActions(FGraphContextMenuBuilder& ContextMenuBuilder) const override;
|
||||||
|
|
||||||
|
// 连接规则
|
||||||
|
virtual const FPinConnectionResponse CanCreateConnection(const UEdGraphPin* A, const UEdGraphPin* B) const override;
|
||||||
|
};
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "WorkflowOrientedApp/WorkflowTabFactory.h"
|
||||||
|
|
||||||
|
class FDialogueAssetEditor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图表Tab工厂
|
||||||
|
*/
|
||||||
|
class FDialogueGraphTabSummoner : public FWorkflowTabFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FDialogueGraphTabSummoner(TSharedPtr<FDialogueAssetEditor> InDialogueEditor);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TWeakPtr<FDialogueAssetEditor> DialogueEditor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** FWorkflowTabFactory Interface */
|
||||||
|
virtual TSharedRef<SWidget> CreateTabBody(const FWorkflowTabSpawnInfo& Info) const override;
|
||||||
|
virtual FText GetTabToolTipText(const FWorkflowTabSpawnInfo& Info) const override;
|
||||||
|
};
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "AssetTypeActions_Base.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class DIALOGUEEDITOR_API FDialogueAssetTypeActions:public FAssetTypeActions_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FDialogueAssetTypeActions(uint32 InAssetCategory);
|
||||||
|
|
||||||
|
/** IAssetTypeActions interface */
|
||||||
|
virtual FText GetName() const override;
|
||||||
|
virtual FColor GetTypeColor() const override;
|
||||||
|
virtual UClass* GetSupportedClass() const override;
|
||||||
|
virtual void OpenAssetEditor(const TArray<UObject*>& InObjects, TSharedPtr<IToolkitHost> EditWithinLevelEditor = TSharedPtr<IToolkitHost>()) override;
|
||||||
|
virtual uint32 GetCategories() override;
|
||||||
|
/** IAssetTypeActions interface */
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32 MyAssetCategory;
|
||||||
|
};
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "DialogueAsset.h"
|
||||||
|
#include "DialogueGraph.h"
|
||||||
|
#include "EdGraph/EdGraphNode.h"
|
||||||
|
#include "DialogueGraphNode_Base.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话节点基类
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class DIALOGUEEDITOR_API UDialogueGraphNode_Base : public UEdGraphNode
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UDialogueGraphNode_Base();
|
||||||
|
/** UEdGraphNode */
|
||||||
|
virtual bool CanUserDeleteNode() const override { return true; }
|
||||||
|
virtual void AllocateDefaultPins() override;
|
||||||
|
|
||||||
|
void SetPostion(FVector2D InPos);
|
||||||
|
void SetDialogueNodeData(UDialogueNodeData_Base* InNodeData) { NodeData = InNodeData; }
|
||||||
|
virtual void InitializeNodeData();
|
||||||
|
virtual void OnPropertiesChanged();
|
||||||
|
UEdGraphPin* GetDefaultInputPin() { return DefaultInputPin; }
|
||||||
|
UDialogueNodeData_Base* GetDialogueNodeData() {return NodeData;}
|
||||||
|
virtual EDialogueNodeType GetDialogueNodeType() { return EDialogueNodeType::None; }
|
||||||
|
// // 节点标题
|
||||||
|
// virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
|
||||||
|
//
|
||||||
|
// // 节点颜色
|
||||||
|
// virtual FLinearColor GetNodeTitleColor() const override;
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
UEdGraphPin* DefaultInputPin = nullptr;
|
||||||
|
UPROPERTY()
|
||||||
|
UDialogueNodeData_Base* NodeData;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "DialogueGraphNode_Base.h"
|
||||||
|
#include "DialogueGraphNode_NPC.generated.h"
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class DIALOGUEEDITOR_API UDialogueGraphNode_NPC: public UDialogueGraphNode_Base
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
UDialogueGraphNode_NPC();
|
||||||
|
|
||||||
|
/** UEdGraphNode Interface */
|
||||||
|
virtual FText GetNodeTitle(ENodeTitleType::Type titalType) const override { return FText::FromString("NPC"); }
|
||||||
|
virtual FLinearColor GetNodeTitleColor() const override { return FLinearColor(FColor::Green); }
|
||||||
|
|
||||||
|
|
||||||
|
virtual EDialogueNodeType GetDialogueNodeType() override { return EDialogueNodeType::NPC;}
|
||||||
|
};
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "DialogueGraphNode_Base.h"
|
||||||
|
#include "DialogueGraphNode_Player.generated.h"
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class UDialogueGraphNode_Player: public UDialogueGraphNode_Base
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
UDialogueGraphNode_Player();
|
||||||
|
|
||||||
|
/** UEdGraphNode Interface */
|
||||||
|
virtual FText GetNodeTitle(ENodeTitleType::Type titalType) const override { return FText::FromString("Player"); }
|
||||||
|
virtual FLinearColor GetNodeTitleColor() const override { return FLinearColor(FColor::Green); }
|
||||||
|
|
||||||
|
|
||||||
|
virtual EDialogueNodeType GetDialogueNodeType() override { return EDialogueNodeType::Player;}
|
||||||
|
};
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "DialogueGraph.h"
|
||||||
|
#include "DialogueGraphNode_Base.h"
|
||||||
|
#include "DialogueGraphNode_Root.generated.h"
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class DIALOGUEEDITOR_API UDialogueGraphNode_Root: public UDialogueGraphNode_Base
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
/** UEdGraphNode Interface */
|
||||||
|
virtual FText GetNodeTitle(ENodeTitleType::Type titalType) const override { return FText::FromString("Start"); }
|
||||||
|
virtual FLinearColor GetNodeTitleColor() const override { return FLinearColor(FColor::Red); }
|
||||||
|
virtual bool CanUserDeleteNode() const override { return false; }
|
||||||
|
virtual void AllocateDefaultPins() override;
|
||||||
|
virtual EDialogueNodeType GetDialogueNodeType() override { return EDialogueNodeType::Root;}
|
||||||
|
};
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Node/DialogueGraphNode_Base.h"
|
||||||
|
#include "SGraphNode.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class DIALOGUEEDITOR_API SDialogueGraphNode: public SGraphNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SLATE_BEGIN_ARGS(SDialogueGraphNode)
|
||||||
|
{}
|
||||||
|
SLATE_END_ARGS()
|
||||||
|
|
||||||
|
void Construct(const FArguments& InArgs, UDialogueGraphNode_Base* InNode);
|
||||||
|
FText GetDialogueText() const;
|
||||||
|
|
||||||
|
/** SGraphNode Interface */
|
||||||
|
virtual TSharedRef<SWidget> CreateNodeContentArea() override;
|
||||||
|
private:
|
||||||
|
TSharedPtr<STextBlock> DialogueText;
|
||||||
|
};
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "SGraphPin.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空pin
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DIALOGUEEDITOR_API SDialogueNoneGraphPin: public SGraphPin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SLATE_BEGIN_ARGS(SDialogueNoneGraphPin)
|
||||||
|
{}
|
||||||
|
SLATE_END_ARGS()
|
||||||
|
void Construct(const FArguments& InArgs, UEdGraphPin* InGraphPinObj) {
|
||||||
|
SGraphPin::Construct(SGraphPin::FArguments(), InGraphPinObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual FSlateColor GetPinColor() const override {
|
||||||
|
return FSlateColor(FLinearColor::White);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话pin
|
||||||
|
*/
|
||||||
|
class DIALOGUEEDITOR_API SDialogueGraphPin: public SGraphPin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SLATE_BEGIN_ARGS(SDialogueGraphPin)
|
||||||
|
{}
|
||||||
|
SLATE_END_ARGS()
|
||||||
|
void Construct(const FArguments& InArgs, UEdGraphPin* InPin);
|
||||||
|
FText GetDialogueText() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** SGraphPin Interface */
|
||||||
|
virtual FSlateColor GetPinColor() const override {return FSlateColor(FLinearColor::White);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TSharedPtr<STextBlock> DialogueText;
|
||||||
|
|
||||||
|
};
|
||||||