A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
DialogueGraphSchema.cpp
Go to the documentation of this file.
1// Copyright Csaba Molnar, Daniel Butum. All Rights Reserved.
3
4#include "Framework/MultiBox/MultiBoxBuilder.h"
5#include "UObject/UObjectIterator.h"
6#include "ScopedTransaction.h"
7#include "AssetData.h"
8#include "GraphEditorActions.h"
9
10#if ENGINE_MINOR_VERSION >= 24
11#include "ToolMenu.h"
12#endif
13
14#include "DialogueGraph.h"
20
21#define LOCTEXT_NAMESPACE "DlgDialogueGraphSchema"
22
23// Initialize static properties
24const FName UDialogueGraphSchema::PIN_CATEGORY_Input(TEXT("ParentInputs"));
25const FName UDialogueGraphSchema::PIN_CATEGORY_Output(TEXT("ChildOutputs"));
26
27const FText UDialogueGraphSchema::NODE_CATEGORY_Dialogue(LOCTEXT("DialogueNodeAction", "Dialogue Node"));
28const FText UDialogueGraphSchema::NODE_CATEGORY_Graph(LOCTEXT("GraphAction", "Graph"));
29const FText UDialogueGraphSchema::NODE_CATEGORY_Convert(LOCTEXT("NodesConvertAction", "Convert Node(s)"));
30
31TArray<TSubclassOf<UDlgNode>> UDialogueGraphSchema::DialogueNodeClasses;
33
35// UDialogueGraphSchema
36void UDialogueGraphSchema::GetPaletteActions(FGraphActionMenuBuilder& ActionMenuBuilder) const
37{
38 GetAllDialogueNodeActions(ActionMenuBuilder);
39 GetCommentAction(ActionMenuBuilder);
40}
41
42bool UDialogueGraphSchema::ConnectionCausesLoop(const UEdGraphPin* InputPin, const UEdGraphPin* OutputPin) const
43{
44 UDialogueGraphNode_Base* InputNode = CastChecked<UDialogueGraphNode_Base>(InputPin->GetOwningNode());
45 UDialogueGraphNode_Base* OutputNode = CastChecked<UDialogueGraphNode_Base>(OutputPin->GetOwningNode());
46
47 // Same Node
48 if (InputNode == OutputNode)
49 {
50 return true;
51 }
52
53 return false;
54}
55
57// Begin EdGraphSchema Interface
58void UDialogueGraphSchema::GetGraphContextActions(FGraphContextMenuBuilder& ContextMenuBuilder) const
59{
60 GetAllDialogueNodeActions(ContextMenuBuilder);
61 GetConvertActions(ContextMenuBuilder, ContextMenuBuilder.CurrentGraph);
62 GetCommentAction(ContextMenuBuilder, ContextMenuBuilder.CurrentGraph);
63
64 // Menu not from a pin, directly right clicked on the graph canvas
65 if (!ContextMenuBuilder.FromPin)
66 {
67 // TODO paste nodes here
68 }
69}
70
71#if ENGINE_MINOR_VERSION >= 24
72void UDialogueGraphSchema::GetContextMenuActions(UToolMenu* Menu, UGraphNodeContextMenuContext* Context) const
73{
74 if (Context->Node && !Context->bIsDebugging)
75 {
76 // Menu for right clicking on node
77 FToolMenuSection& Section = Menu->AddSection("DialogueGraphSchemaNodeActions", LOCTEXT("NodeActionsMenuHeader", "Node Actions"));
78
79 // This action is handled in UDialogueGraphSchema::BreakNodeLinks, and the action is registered in SGraphEditorImpl (not by us)
80 Section.AddMenuEntry(FGraphEditorCommands::Get().BreakNodeLinks);
81 }
82
83 // The rest of the menus are implemented in the each nodes GetContextMenuActions method
84 Super::GetContextMenuActions(Menu, Context);
85}
86
87#else
88
90 const UEdGraph* CurrentGraph,
91 const UEdGraphNode* InGraphNode,
92 const UEdGraphPin* InGraphPin,
93 FMenuBuilder* MenuBuilder,
94 bool bIsDebugging
95) const
96{
97 if (InGraphNode && !bIsDebugging)
98 {
99 // Menu for right clicking on node
100 MenuBuilder->BeginSection("DialogueGraphSchemaNodeActions", LOCTEXT("NodeActionsMenuHeader", "Node Actions"));
101 {
102 // This action is handled in UDialogueGraphSchema::BreakNodeLinks, and the action is registered in SGraphEditorImpl (not by us)
103 MenuBuilder->AddMenuEntry(FGraphEditorCommands::Get().BreakNodeLinks);
104 }
105 MenuBuilder->EndSection();
106 }
107
108 // The rest of the menus are implemented in the each nodes GetContextMenuActions method
109 Super::GetContextMenuActions(CurrentGraph, InGraphNode, InGraphPin, MenuBuilder, bIsDebugging);
110}
111#endif // ENGINE_MINOR_VERSION >= 24
112
114{
115 // This should only be called on empty graphs
116 check(Graph.Nodes.Num() == 0);
117 UDialogueGraph* DialogueGraph = CastChecked<UDialogueGraph>(&Graph);
118
119 // Create, link and position nodes
120 DialogueGraph->CreateGraphNodesFromDialogue();
121 DialogueGraph->LinkGraphNodesFromDialogue();
122 DialogueGraph->AutoPositionGraphNodes();
123
124 // TODO(vampy): Fix editor crash
125 //SetNodeMetaData(ResultRootNode, FNodeMetadata::DefaultGraphNode);
126}
127
128FPinConnectionResponse UDialogueGraphSchema::MovePinLinks(UEdGraphPin& MoveFromPin, UEdGraphPin& MoveToPin, bool bIsIntermediateMove, bool bNotifyLinkedNodes) const
129{
130 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("ConnectionMovePinLinks", "Move Pin Links Not implemented"));
131}
132
133FPinConnectionResponse UDialogueGraphSchema::CopyPinLinks(UEdGraphPin& CopyFromPin, UEdGraphPin& CopyToPin, bool bIsIntermediateCopy) const
134{
135 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("ConnectionMovePinLinks", "Copy Pin Links Not implemented"));
136}
137
138const FPinConnectionResponse UDialogueGraphSchema::CanCreateConnection(const UEdGraphPin* PinA, const UEdGraphPin* PinB) const
139{
140 // Make sure the pins are not on the same node
141 if (PinA->GetOwningNode() == PinB->GetOwningNode())
142 {
143 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("ConnectionSameNode", "Both are on the same node"));
144 }
145
146 // Causes loop
147 if (ConnectionCausesLoop(PinA, PinB))
148 {
149 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("ConnectionLoop", "Connection would cause loop"));
150 }
151
152 // Compare the directions
153 const UDialogueGraphNode_Base* SourceNode = CastChecked<UDialogueGraphNode_Base>(PinA->GetOwningNode());
154 const UDialogueGraphNode_Base* TargetNode = CastChecked<UDialogueGraphNode_Base>(PinB->GetOwningNode());
155
156 // Does the source Node accept output connection?
157 if (!SourceNode->CanHaveOutputConnections())
158 {
159 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, TEXT("Cannot wire an edge from this node because it does not accept output connection "));
160 }
161
162 // Does the targe Node accept input connection?
163 if (!TargetNode->CanHaveInputConnections())
164 {
165 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, TEXT("Cannot wire an edge to this node because it does not accept input connection "));
166 }
167
168 // Only allow one connection from an output (parent node)
169 if (SourceNode->HasOutputConnectionToNode(TargetNode))
170 {
171 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("ConnectionAlreadyMade", "Connection between nodes already made"));
172 }
173
174 const bool bPinAIsEdge = SourceNode->IsA(UDialogueGraphNode_Edge::StaticClass());
175 const bool bPinBIsEdge = TargetNode->IsA(UDialogueGraphNode_Edge::StaticClass());
176 // Can't connect edges to edges
177 if (bPinAIsEdge && bPinBIsEdge)
178 {
179 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, TEXT("Cannot wire an edge to an edge"));
180 }
181
182 // Handle connection from and Edge to a Node OR Node to an Edge
183 // Edges connections are exclusive so we break them
184 if (bPinAIsEdge)
185 {
186 return FPinConnectionResponse(CONNECT_RESPONSE_BREAK_OTHERS_A, TEXT("SHOULD NOT BE VISIBLE"));
187 }
188 if (bPinBIsEdge)
189 {
190 return FPinConnectionResponse(CONNECT_RESPONSE_BREAK_OTHERS_B, TEXT("SHOULD NOT BE VISIBLE"));
191 }
192
193 // Handle Connection from a Node to a Node
194 // Create and Edge by the means of conversion
195 if (!bPinAIsEdge && !bPinBIsEdge)
196 {
197 // Calls CreateAutomaticConversionNodeAndConnections()
198 return FPinConnectionResponse(CONNECT_RESPONSE_MAKE_WITH_CONVERSION_NODE, TEXT("Create an Edge"));
199 }
200
201 return FPinConnectionResponse(CONNECT_RESPONSE_MAKE, FText::GetEmpty());
202}
203
204bool UDialogueGraphSchema::TryCreateConnection(UEdGraphPin* PinA, UEdGraphPin* PinB) const
205{
206 // Happens when connecting pin to itself, seems to be a editor bug
207 if (PinA->GetOwningNode() == PinB->GetOwningNode())
208 {
209 return false;
210 }
211
212 // Handle the CONNECT_RESPONSE_BREAK_OTHERS, this should handle all cases, because there is only
213 // one input pin and that is the only one which will loose it's former parent
214 UEdGraphPin* FormerParentOutputPin = nullptr;
215 {
216 // Usually the InputPin is the PinB
217// const ECanCreateConnectionResponse Response = CanCreateConnection(PinA, PinB).Response;
218// if (Response == CONNECT_RESPONSE_BREAK_OTHERS_B || Response == CONNECT_RESPONSE_BREAK_OTHERS_A)
219// {
220// // Should only happen to edges
221// UEdGraphPin* InputPin = nullptr;
222// UEdGraphPin* OutputPin = nullptr;
223// verify(CategorizePinsByDirection(PinA, PinB, /*out*/ InputPin, /*out*/ OutputPin));
224// check(InputPin->GetOwningNode()->IsA(UDialogueGraphNode_Edge::StaticClass()));
225// FormerParentOutputPin = InputPin->LinkedTo[0];
226// }
227 }
228
229 // Mark for undo system, we do not know if there is transaction so just mark without verifying
230 // This mostly fixes crashing on undo when there is a drag operation
231 UEdGraph* Graph = PinA->GetOwningNode()->GetGraph();
232 {
233 PinA->GetOwningNode()->Modify();
234 PinB->GetOwningNode()->Modify();
235 Graph->Modify();
237 }
238
239 const bool bModified = Super::TryCreateConnection(PinA, PinB);
240 if (bModified)
241 {
242 // Notify former parent
243 if (FormerParentOutputPin != nullptr)
244 {
245 FormerParentOutputPin->GetOwningNode()->PinConnectionListChanged(FormerParentOutputPin);
246 }
247
248 UDialogueGraphNode_Base* NodeB = CastChecked<UDialogueGraphNode_Base>(PinB->GetOwningNode());
249 // Update the internal structure (recompile of the Dialogue Node/Graph Nodes)
250 NodeB->GetDialogue()->CompileDialogueNodesFromGraphNodes();
251 }
252
253 // Reset the value
255
256 return bModified;
257}
258
259bool UDialogueGraphSchema::CreateAutomaticConversionNodeAndConnections(UEdGraphPin* PinA, UEdGraphPin* PinB) const
260{
261 UDialogueGraphNode* NodeA = CastChecked<UDialogueGraphNode>(PinA->GetOwningNode());
262 UDialogueGraphNode* NodeB = CastChecked<UDialogueGraphNode>(PinB->GetOwningNode());
263 UEdGraph* Graph = NodeA->GetGraph();
264
265 // NOTE: NodeB does not have a valid position yet so we can't use it
266 UDialogueGraphNode_Edge* GraphNode_Edge =
267 FDialogueEditorUtilities::SpawnGraphNodeFromTemplate<UDialogueGraphNode_Edge>(
268 Graph, NodeA->GetDefaultEdgePosition(), false
269 );
270
271 // Create proxy connection from output -> input
272 if (PinA->Direction == EGPD_Output)
273 {
274 GraphNode_Edge->CreateConnections(NodeA, NodeB);
275 }
276 else
277 {
278 GraphNode_Edge->CreateConnections(NodeB, NodeA);
279 }
280
281 // Was this from a modify drag and drop event? copy from the previous node
283 {
284 // Copy the data from the old node, without the target index
285 FDlgEdge NewEdge = GraphNode_Edge->GetDialogueEdge();
286 const int32 NewTargetIndex = NewEdge.TargetIndex;
287
288 NewEdge = GraphNode_Edge_DragDop->GetDialogueEdge();
289 NewEdge.TargetIndex = NewTargetIndex;
290
291 // Propagate to Node
292 GraphNode_Edge->SetDialogueEdge(NewEdge);
293 GraphNode_Edge->PostEditChange();
294 }
295 Graph->NotifyGraphChanged();
296
297 return true;
298}
299
301{
302 return true;
303}
304
306{
307 // NOTE: The SGraphEditorImpl::BreakNodeLinks that calls this (method) has the transaction declared, so do not make another one here.
308 UEdGraph* Graph = TargetNode.GetGraph();
310
311 // Mark for undo system
312 verify(Graph->Modify());
313 verify(TargetNode.Modify());
314 verify(Dialogue->Modify());
315
316 Super::BreakNodeLinks(TargetNode);
317
318#if DO_CHECK
319 if (UDialogueGraphNode* GraphNode = Cast<UDialogueGraphNode>(&TargetNode))
320 {
321 GraphNode->CheckAll();
322 }
323#endif
324
325 Dialogue->CompileDialogueNodesFromGraphNodes();
326}
327
328void UDialogueGraphSchema::BreakPinLinks(UEdGraphPin& TargetPin, bool bSendsNodeNotifcation) const
329{
330 const FScopedTransaction Transaction(LOCTEXT("GraphEd_BreakPinLinks", "Dialogue Editor: Break Pin Links"));
331 UEdGraphNode* Node = TargetPin.GetOwningNode();
332 UEdGraph* Graph = Node->GetGraph();
334
335 // Mark for undo system
336 verify(Node->Modify());
337 verify(Graph->Modify());
338 verify(Dialogue->Modify());
339 // Modify() is called in BreakLinkTo on the TargetPin
340
341 Super::BreakPinLinks(TargetPin, bSendsNodeNotifcation);
342
343#if DO_CHECK
344 if (UDialogueGraphNode* GraphNode = Cast<UDialogueGraphNode>(TargetPin.GetOwningNode()))
345 {
346 GraphNode->CheckAll();
347 }
348#endif
349
350 // If this would notify the node then we need to compile the Dialogue
351 if (bSendsNodeNotifcation)
352 {
353 // Recompile
354 Dialogue->CompileDialogueNodesFromGraphNodes();
355 }
356}
357
358void UDialogueGraphSchema::BreakSinglePinLink(UEdGraphPin* SourcePin, UEdGraphPin* TargetPin) const
359{
360 const FScopedTransaction Transaction(LOCTEXT("GraphEd_BreakSinglePinLink", "Dialogue Editor: Break Pin Link"));
361 // Modify() is called in BreakLinkTo
362 Super::BreakSinglePinLink(SourcePin, TargetPin);
363}
364
365void UDialogueGraphSchema::DroppedAssetsOnGraph(const TArray<FAssetData>& Assets, const FVector2D& GraphPosition, UEdGraph* Graph) const
366{
367
368}
369
370void UDialogueGraphSchema::DroppedAssetsOnNode(const TArray<FAssetData>& Assets, const FVector2D& GraphPosition, UEdGraphNode* Node) const
371{
372
373}
374// End EdGraphSchema Interface
376
378// Begin own functions
379void UDialogueGraphSchema::BreakLinkTo(UEdGraphPin* FromPin, UEdGraphPin* ToPin, bool bSendsNodeNotifcation) const
380{
381 const FScopedTransaction Transaction(LOCTEXT("GraphEd_BreakPinLink", "Dialogue Editor: Break Pin Link"));
382 UEdGraphNode* FromNode = FromPin->GetOwningNode();
383 UEdGraphNode* ToNode = ToPin->GetOwningNode();
384 UEdGraph* Graph = FromNode->GetGraph();
386
387 // Mark for undo system
388 verify(FromNode->Modify());
389 verify(ToNode->Modify());
390 verify(Graph->Modify());
391 verify(Dialogue->Modify());
392
393 // Break
394 FromPin->BreakLinkTo(ToPin);
395
396 // Notify
397 FromNode->PinConnectionListChanged(FromPin);
398 ToNode->PinConnectionListChanged(ToPin);
399 if (bSendsNodeNotifcation)
400 {
401 FromNode->NodeConnectionListChanged();
402 ToNode->NodeConnectionListChanged();
403 }
404
405#if DO_CHECK
406 if (UDialogueGraphNode* GraphNode = Cast<UDialogueGraphNode>(FromNode))
407 {
408 GraphNode->CheckAll();
409 }
410 if (UDialogueGraphNode* GraphNode = Cast<UDialogueGraphNode>(ToNode))
411 {
412 GraphNode->CheckAll();
413 }
414#endif
415
416 // If this would notify the node then we need to Recompile the Dialogue
417 if (bSendsNodeNotifcation)
418 {
419 Dialogue->CompileDialogueNodesFromGraphNodes();
420 }
421}
422
423void UDialogueGraphSchema::GetCommentAction(FGraphActionMenuBuilder& ActionMenuBuilder, const UEdGraph* CurrentGraph) const
424{
425 // Do not allow to spawn a comment when we drag are dragging from a selected pin.
426 if (ActionMenuBuilder.FromPin)
427 {
428 return;
429 }
430
431 // The rest of the comment actions are in the UEdGraphSchema::GetContextMenuActions
432 const bool bIsManyNodesSelected = CurrentGraph ? GetNodeSelectionCount(CurrentGraph) > 0 : false;
433 const FText MenuDescription = bIsManyNodesSelected ?
434 LOCTEXT("CreateCommentAction", "Create Comment from Selection") : LOCTEXT("AddCommentAction", "Add Comment...");
435 const FText ToolTip = LOCTEXT("CreateCommentToolTip", "Creates a comment.");
436 constexpr int32 Grouping = 1;
437
438 TSharedPtr<FNewComment_DialogueGraphSchemaAction> NewAction(new FNewComment_DialogueGraphSchemaAction(
439 NODE_CATEGORY_Graph, MenuDescription, ToolTip, Grouping));
440 ActionMenuBuilder.AddAction(NewAction);
441}
442
443void UDialogueGraphSchema::GetConvertActions(FGraphActionMenuBuilder& ActionMenuBuilder, const UEdGraph* CurrentGraph) const
444{
445 if (ActionMenuBuilder.FromPin || !IsValid(CurrentGraph))
446 {
447 return;
448 }
449
450 const TSet<UObject*> SelectedNodes = FDialogueEditorUtilities::GetSelectedNodes(CurrentGraph);
451 int32 Grouping = 1;
452
453 // Try conversion from speech nodes to a sequence node
454 {
455 TArray<UDialogueGraphNode*> SelectedGraphNodes;
456 if (FDialogueEditorUtilities::CanConvertSpeechNodesToSpeechSequence(SelectedNodes, SelectedGraphNodes))
457 {
458 const FText MenuDescription =
459 LOCTEXT("ConvertSpeechNodesToSequenceNodeDesc", "Converts selected Speech node(s) to a Speech Sequence Node");
460 const FText ToolTip =
461 LOCTEXT("ConvertSpeechNodesToSequenceNodeToolTip", "Converts selected (compresses) linear Speech node(s) to a Speech Sequence Node");
462
463 TSharedPtr<FConvertSpeechNodesToSpeechSequence_DialogueGraphSchemaAction> NewAction(
466 MenuDescription,
467 ToolTip,
468 Grouping++,
469 SelectedGraphNodes
470 )
471 );
472 ActionMenuBuilder.AddAction(NewAction);
473 }
474 }
475}
476
477void UDialogueGraphSchema::GetAllDialogueNodeActions(FGraphActionMenuBuilder& ActionMenuBuilder) const
478{
480 FText ToolTip, MenuDesc;
481
482 // when dragging from an input pin
483 if (ActionMenuBuilder.FromPin == nullptr)
484 {
485 // Just right clicked on the empty graph
486 ToolTip = LOCTEXT("NewDialogueNodeTooltip", "Adds {Name} to the graph");
487 MenuDesc = LOCTEXT("NewDialogueNodeMenuDescription", "{Name}");
488 }
489 else if (ActionMenuBuilder.FromPin->Direction == EGPD_Input)
490 {
491 // From an input pin
492 ToolTip = LOCTEXT("NewDialogueNodeTooltip_FromInputPin", "Adds {Name} to the graph as a parent to the current node");
493 MenuDesc = LOCTEXT("NewDialogueNodeMenuDescription_FromInputPin", "Add {Name} parent");
494 }
495 else
496 {
497 // From an output pin
498 check(ActionMenuBuilder.FromPin->Direction == EGPD_Output);
499 ToolTip = LOCTEXT("NewDialogueNodeTooltip_FromOutputPin", "Adds {Name} to the graph as a child to the current node");
500 MenuDesc = LOCTEXT("NewDialogueNodeMenuDescription_FromOutputPin", "Add {Name} child");
501 }
502
503 int32 Grouping = 0;
504 FFormatNamedArguments Arguments;
505
506 // Generate menu actions for all the node types
507 for (TSubclassOf<UDlgNode> DialogueNodeClass : DialogueNodeClasses)
508 {
509 const UDlgNode* DialogueNode = DialogueNodeClass->GetDefaultObject<UDlgNode>();
510 Arguments.Add(TEXT("Name"), FText::FromString(DialogueNode->GetNodeTypeString()));
511
512 TSharedPtr<FNewNode_DialogueGraphSchemaAction> Action(new FNewNode_DialogueGraphSchemaAction(
513 NODE_CATEGORY_Dialogue, FText::Format(MenuDesc, Arguments), FText::Format(ToolTip, Arguments),
514 Grouping++, DialogueNodeClass));
515 ActionMenuBuilder.AddAction(Action);
516 }
517}
518
520{
522 {
523 return;
524 }
525
526 // Construct list of non-abstract dialogue node classes.
527 for (TObjectIterator<UClass> It; It; ++It)
528 {
529 if (It->IsChildOf(UDlgNode::StaticClass()) && !It->HasAnyClassFlags(CLASS_Abstract))
530 {
531 DialogueNodeClasses.Add(*It);
532 }
533 }
534
535// DialogueNodeClasses.Sort();
537}
538//~ End own functions
540
541#undef LOCTEXT_NAMESPACE
static UDialogueGraphNode_Edge * GetLastTargetGraphEdgeBeforeDrag(const UEdGraph *Graph)
static void SetLastTargetGraphEdgeBeforeDrag(const UEdGraph *Graph, UDialogueGraphNode_Edge *InEdge)
static bool CanConvertSpeechNodesToSpeechSequence(const TSet< UObject * > &SelectedNodes, TArray< UDialogueGraphNode * > &OutSelectedGraphNodes)
static const TSet< UObject * > GetSelectedNodes(const UEdGraph *Graph)
static UDlgDialogue * GetDialogueForGraph(const UEdGraph *Graph)
void LinkGraphNodesFromDialogue() const
void AutoPositionGraphNodes() const
void CreateGraphNodesFromDialogue()
virtual bool HasOutputConnectionToNode(const UEdGraphNode *TargetNode) const
virtual bool CanHaveInputConnections() const
UDlgDialogue * GetDialogue() const
virtual bool CanHaveOutputConnections() const
const FDlgEdge & GetDialogueEdge() const
void CreateConnections(UDialogueGraphNode *ParentNode, UDialogueGraphNode *ChildNode)
void SetDialogueEdge(const FDlgEdge &InEdge)
FIntPoint GetDefaultEdgePosition() const
void BreakSinglePinLink(UEdGraphPin *SourcePin, UEdGraphPin *TargetPin) const override
static const FText NODE_CATEGORY_Convert
void GetContextMenuActions(const UEdGraph *CurrentGraph, const UEdGraphNode *InGraphNode, const UEdGraphPin *InGraphPin, FMenuBuilder *MenuBuilder, bool bIsDebugging) const override
void BreakPinLinks(UEdGraphPin &TargetPin, bool bSendsNodeNotifcation) const override
static const FName PIN_CATEGORY_Output
void BreakNodeLinks(UEdGraphNode &TargetNode) const override
void GetCommentAction(FGraphActionMenuBuilder &ActionMenuBuilder, const UEdGraph *CurrentGraph=nullptr) const
const FPinConnectionResponse CanCreateConnection(const UEdGraphPin *PinA, const UEdGraphPin *PinB) const override
bool ShouldHidePinDefaultValue(UEdGraphPin *Pin) const override
void GetAllDialogueNodeActions(FGraphActionMenuBuilder &ActionMenuBuilder) const
static TArray< TSubclassOf< UDlgNode > > DialogueNodeClasses
bool TryCreateConnection(UEdGraphPin *PinA, UEdGraphPin *PinB) const override
static const FText NODE_CATEGORY_Graph
void GetPaletteActions(FGraphActionMenuBuilder &ActionMenuBuilder) const
void BreakLinkTo(UEdGraphPin *TargetPin, UEdGraphPin *ToPin, bool bSendsNodeNotifcation) const
void DroppedAssetsOnGraph(const TArray< FAssetData > &Assets, const FVector2D &GraphPosition, UEdGraph *Graph) const override
static void InitDialogueNodeClasses()
void GetConvertActions(FGraphActionMenuBuilder &ActionMenuBuilder, const UEdGraph *CurrentGraph) const
void GetGraphContextActions(FGraphContextMenuBuilder &ContextMenuBuilder) const override
FPinConnectionResponse CopyPinLinks(UEdGraphPin &CopyFromPin, UEdGraphPin &CopyToPin, bool bIsIntermediateCopy=false) const override
void CreateDefaultNodesForGraph(UEdGraph &Graph) const override
bool CreateAutomaticConversionNodeAndConnections(UEdGraphPin *PinA, UEdGraphPin *PinB) const override
bool ConnectionCausesLoop(const UEdGraphPin *InputPin, const UEdGraphPin *OutputPin) const
FPinConnectionResponse MovePinLinks(UEdGraphPin &MoveFromPin, UEdGraphPin &MoveToPin, bool bIsIntermediateMove=false, bool bNotifyLinkedNodes=false) const override
static bool bDialogueNodeClassesInitialized
void DroppedAssetsOnNode(const TArray< FAssetData > &Assets, const FVector2D &GraphPosition, UEdGraphNode *Node) const override
static const FName PIN_CATEGORY_Input
static const FText NODE_CATEGORY_Dialogue
int32 GetNodeSelectionCount(const UEdGraph *Graph) const override
UCLASS(BlueprintType, Meta = (DisplayThumbnail = "true"))
Definition DlgDialogue.h:85
UCLASS(BlueprintType, Abstract, EditInlineNew, ClassGroup = "Dialogue")
Definition DlgNode.h:40
USTRUCT(BlueprintType)
Definition DlgEdge.h:25
int32 TargetIndex
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Dialogue|Edge", Meta = (ClampMin = -1))
Definition DlgEdge.h:126