A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
ConvertSpeechNodesToSpeechSequence_DialogueGraphSchemaAction.cpp
Go to the documentation of this file.
1// Copyright Csaba Molnar, Daniel Butum. All Rights Reserved.
3
4#include "ScopedTransaction.h"
5
7#include "DlgDialogue.h"
12
13#define LOCTEXT_NAMESPACE "ConvertSpeechNodesToSpeechSequence_DialogueGraphSchemaAction"
14
16// FConvertSpeechNodesToSpeechSequence_DialogueGraphSchemaAction
18 const FVector2D Location, bool bSelectNewNode/* = true*/)
19{
20 // Should have been stopped in GetConvertActions
21 check(SelectedGraphNodes.Num() > 0);
22 const FScopedTransaction Transaction(LOCTEXT("DialogueditorConvertSpeechNodesToSpeechSequence", "Convert Speech Nodes to a Sequence Node"));
24
25 // Disable compiling for optimization
26 Dialogue->DisableCompileDialogue();
27
28 // Step 1. Create the final speech sequence
29 UDialogueGraphNode* GraphNode_SpeechSequence = FNewNode_DialogueGraphSchemaAction::SpawnGraphNodeWithDialogueNodeFromTemplate<UDialogueGraphNode>(
30 ParentGraph, UDlgNode_SpeechSequence::StaticClass(), Location, bSelectNewNode);
31
32 // Step 2. Copy all selected graph nodes into the speech sequence
33 UDlgNode_SpeechSequence* DialogueNode_SpeechSequence =
34 GraphNode_SpeechSequence->GetMutableDialogueNode<UDlgNode_SpeechSequence>();
35 TArray<FDlgSpeechSequenceEntry>* SpeechSequence = DialogueNode_SpeechSequence->GetMutableNodeSpeechSequence();
36 for (UDialogueGraphNode* GraphNode : SelectedGraphNodes)
37 {
38 const UDlgNode_Speech& DialogueNode_Speech = GraphNode->GetDialogueNode<UDlgNode_Speech>();
39 auto SequenceEntry = FDlgSpeechSequenceEntry{};
40 SequenceEntry.Speaker = DialogueNode_Speech.GetNodeParticipantName();
41 SequenceEntry.Text = DialogueNode_Speech.GetNodeText();
42 SequenceEntry.NodeData = DialogueNode_Speech.GetNodeData();
43 SequenceEntry.SpeakerState = DialogueNode_Speech.GetSpeakerState();
44 SequenceEntry.VoiceSoundWave = DialogueNode_Speech.GetNodeVoiceSoundBase();
45 SequenceEntry.VoiceDialogueWave = DialogueNode_Speech.GetNodeVoiceDialogueWave();
46 SequenceEntry.GenericData = DialogueNode_Speech.GetNodeGenericData();
47
48 // Set edge if any
49 const TArray<FDlgEdge>& Children = DialogueNode_Speech.GetNodeChildren();
50 // Get only the first edge, as there should be only one anyways (besides the last node)
51 if (Children.Num() > 0)
52 {
53 SequenceEntry.EdgeText = Children[0].GetUnformattedText();
54 }
55
56 SpeechSequence->Add(SequenceEntry);
57 }
58 DialogueNode_SpeechSequence->AutoGenerateInnerEdges();
59
60 // Step 3. Copy existing connections from the first and last node in the sequence
61 // Replace connections from parents
62 const UDialogueGraphNode* FirstSelectedGraphNode = SelectedGraphNodes[0];
63 FDialogueEditorUtilities::ReplaceParentConnectionsToNode(FirstSelectedGraphNode, GraphNode_SpeechSequence);
64
65 // Copy connections from the last node to the speech sequence
66 const UDialogueGraphNode* LastSelectedNode = SelectedGraphNodes.Last();
67 FDialogueEditorUtilities::CopyNodeChildren(LastSelectedNode, GraphNode_SpeechSequence);
68
69 // Step 4. Copy existing enter events and/or conditions from the first node in the sequence
70 if (FirstSelectedGraphNode->HasEnterConditions() || FirstSelectedGraphNode->HasEnterEvents())
71 {
72 const UDlgNode_Speech& DialogueNode_Speech = FirstSelectedGraphNode->GetDialogueNode<UDlgNode_Speech>();
73 if (FirstSelectedGraphNode->HasEnterConditions())
74 {
75 TArray<FDlgCondition> EnterConditions = DialogueNode_Speech.GetNodeEnterConditions();
76 for (FDlgCondition& Condition : EnterConditions)
77 {
78 if (Condition.CustomCondition)
79 {
80 Condition.CustomCondition = DuplicateObject(Condition.CustomCondition, DialogueNode_SpeechSequence);
81 }
82 }
83 DialogueNode_SpeechSequence->SetNodeEnterConditions(EnterConditions);
84 }
85 if (FirstSelectedGraphNode->HasEnterEvents())
86 {
87 TArray<FDlgEvent> EnterEvents = DialogueNode_Speech.GetNodeEnterEvents();
88 for (FDlgEvent& Event : EnterEvents)
89 {
90 if (Event.CustomEvent)
91 {
92 Event.CustomEvent = DuplicateObject(Event.CustomEvent, DialogueNode_SpeechSequence);
93 }
94 }
95 DialogueNode_SpeechSequence->SetNodeEnterEvents(EnterEvents);
96 }
97 }
98
99 // Step 5. Remove the nodes, this will break the existing input/output connections of the nodes
100 for (UDialogueGraphNode* GraphNode : SelectedGraphNodes)
102
103#if DO_CHECK
104 GraphNode_SpeechSequence->CheckAll();
105 for (UDialogueGraphNode* ParentNode : GraphNode_SpeechSequence->GetParentNodes())
106 {
107 ParentNode->CheckAll();
108 }
109 for (UDialogueGraphNode* ChildNode : GraphNode_SpeechSequence->GetChildNodes())
110 {
111 ChildNode->CheckAll();
112 }
113#endif
114 Dialogue->EnableCompileDialogue();
115 Dialogue->CompileDialogueNodesFromGraphNodes();
116 Dialogue->PostEditChange();
117 Dialogue->MarkPackageDirty();
118 ParentGraph->NotifyGraphChanged();
119
120 return GraphNode_SpeechSequence;
121}
122
123#undef LOCTEXT_NAMESPACE
static void CopyNodeChildren(const UDialogueGraphNode *FromNode, UDialogueGraphNode *ToNode)
static void ReplaceParentConnectionsToNode(const UDialogueGraphNode *OldNode, const UDialogueGraphNode *NewNode)
static bool RemoveNode(UEdGraphNode *NodeToRemove)
static UDlgDialogue * GetDialogueForGraph(const UEdGraph *Graph)
bool HasEnterEvents() const
TArray< UDialogueGraphNode * > GetChildNodes() const
DlgNodeType * GetMutableDialogueNode()
TArray< UDialogueGraphNode * > GetParentNodes() const
const DlgNodeType & GetDialogueNode() const
void CheckAll() const override
bool HasEnterConditions() const
UCLASS(BlueprintType, Meta = (DisplayThumbnail = "true"))
Definition DlgDialogue.h:85
UCLASS(BlueprintType, ClassGroup = "Dialogue")
FName SpeakerState
UPROPERTY(EditAnywhere, Category = "Dialogue|Node")
const FText & GetNodeText() const override
UFUNCTION(BlueprintPure, Category = "Dialogue|Node")
UDlgNodeData * NodeData
UPROPERTY(EditAnywhere, Instanced, Category = "Dialogue|Node")
FName GetSpeakerState() const override
UFUNCTION(BlueprintPure, Category = "Dialogue|Node")
FText Text
UPROPERTY(EditAnywhere, Category = "Dialogue|Node", Meta = (MultiLine = true))
UObject * GetNodeGenericData() const override
UFUNCTION(BlueprintPure, Category = "Dialogue|Node")
UDialogueWave * GetNodeVoiceDialogueWave() const override
UFUNCTION(BlueprintPure, Category = "Dialogue|Node")
USoundBase * GetNodeVoiceSoundBase() const override
UFUNCTION(BlueprintPure, Category = "Dialogue|Node")
UDialogueWave * VoiceDialogueWave
UPROPERTY(EditAnywhere, Category = "Dialogue|Node", Meta = (DlgSaveOnlyReference))
UObject * GenericData
UPROPERTY(EditAnywhere, Category = "Dialogue|Node", Meta = (DlgSaveOnlyReference))
UDlgNodeData * GetNodeData() const override
UFUNCTION(BlueprintPure, Category = "Dialogue|Node")
USoundBase * VoiceSoundWave
UPROPERTY(EditAnywhere, Category = "Dialogue|Node", Meta = (DlgSaveOnlyReference))
UCLASS(BlueprintType, ClassGroup = "Dialogue")
TArray< FDlgSpeechSequenceEntry > * GetMutableNodeSpeechSequence()
virtual const TArray< FDlgEdge > & GetNodeChildren() const
Gets this nodes children (edges) as a const/mutable array.
Definition DlgNode.h:184
virtual FName GetNodeParticipantName() const
UFUNCTION(BlueprintPure, Category = "Dialogue|Node")
Definition DlgNode.h:127
virtual const TArray< FDlgEvent > & GetNodeEnterEvents() const
UFUNCTION(BlueprintPure, Category = "Dialogue|Node")
Definition DlgNode.h:170
virtual void SetNodeEnterConditions(const TArray< FDlgCondition > &InEnterConditions)
Definition DlgNode.h:147
virtual void SetNodeEnterEvents(const TArray< FDlgEvent > &InEnterEvents)
Definition DlgNode.h:172
virtual const TArray< FDlgCondition > & GetNodeEnterConditions() const
UFUNCTION(BlueprintPure, Category = "Dialogue|Node")
Definition DlgNode.h:145
UEdGraphNode * PerformAction(UEdGraph *ParentGraph, UEdGraphPin *FromPin, const FVector2D Location, bool bSelectNewNode=true) override
USTRUCT(Blueprintable)
USTRUCT(BlueprintType)
Definition DlgEvent.h:59
USTRUCT(BlueprintType)