Download

Unreal crashes when adding a EdGraphNode to EdGraph (For custom plugin)

I am trying to write a plugin for dialogue, quest and state machines. I was off to a good start but for whatever reason when I try to create a new “EdGraphNode” it crashes and I do not understand why. Ill post my code bellow. I am getting references from here. UE4 Asset Editor Graph Node (easycomplex-tech.com)

The crash happens on line 145 of “FluidNarratorGraphEditor”


EdGraph->CreateNarratorGraphNode(FVector2D(0, 0));


//-------------------------------------------Property Identifiers-----------------------------------------------------------

struct FFluidNarratorAssetEditorTabs
{
static const FName DetailsID;
static const FName ViewportID;
};

const FName FFluidNarratorAssetEditorTabs::DetailsID(TEXT("NarratorGraphDetails"));
const FName FFluidNarratorAssetEditorTabs::ViewportID(TEXT("Viewport"));



//-------------------------------------------Constructor-----------------------------------------------------------

FluidNarratorGraphEditor::FluidNarratorGraphEditor()
{
ViewportWidget = nullptr;
PropertyWidget = nullptr;
Graph = nullptr;
EdGraph = nullptr;
CurrentGraphNodeEffectToEdit = nullptr;
}

FluidNarratorGraphEditor::~FluidNarratorGraphEditor()
{
//UPackage::PackageSavedEvent.Remove(OnPackageSavedDelegateHandle);
}

//-------------------------------------------IToolkit interface-----------------------------------------------------------

void FluidNarratorGraphEditor::RegisterTabSpawners(const TSharedRef<FTabManager>& InTabManager)
{
FAssetEditorToolkit::RegisterTabSpawners(InTabManager);

InTabManager->RegisterTabSpawner(FFluidNarratorAssetEditorTabs::ViewportID, FOnSpawnTab::CreateSP(this, &FluidNarratorGraphEditor::SpawnTabViewport))
.SetDisplayName(FText::FromString("Viewport"))
.SetIcon(FSlateIcon(FEditorStyle::GetStyleSetName(), "GraphEditor.EventGraph_16x"));

InTabManager->RegisterTabSpawner(FFluidNarratorAssetEditorTabs::DetailsID, FOnSpawnTab::CreateSP(this, &FluidNarratorGraphEditor::SpawnTabProperties))
.SetDisplayName(FText::FromString("Details"))
.SetIcon(FSlateIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.Tabs.Details"));
}

void FluidNarratorGraphEditor::UnregisterTabSpawners(const TSharedRef<FTabManager>& InTabManager)
{
FAssetEditorToolkit::UnregisterTabSpawners(InTabManager);

InTabManager->UnregisterTabSpawner(FFluidNarratorAssetEditorTabs::ViewportID);
InTabManager->UnregisterTabSpawner(FFluidNarratorAssetEditorTabs::DetailsID);
}


//-------------------------------------------FAssetEditorToolkit | FSerializableObject interface-----------------------------------------------------------

FName FluidNarratorGraphEditor::GetToolkitFName() const
{
return FName("Fluid Narrator Graph");
}

FText FluidNarratorGraphEditor::GetBaseToolkitName() const
{
return FText::FromString("Fluid Narrator Graph");
}

FText FluidNarratorGraphEditor::GetToolkitName() const
{
return FText::FromString("Fluid Narrator Graph");
}

FText FluidNarratorGraphEditor::GetToolkitToolTipText() const
{
return FText::FromString("Fluid Narrator Graph");
}

FLinearColor FluidNarratorGraphEditor::GetWorldCentricTabColorScale() const
{
return FLinearColor();
}

FString FluidNarratorGraphEditor::GetWorldCentricTabPrefix() const
{
return "Fluid Narrator Graph";
}

FString FluidNarratorGraphEditor::GetDocumentationLink() const
{
return "Fluid Narrator Graph";
}

void FluidNarratorGraphEditor::SaveAsset_Execute()
{
}

void FluidNarratorGraphEditor::AddReferencedObjects(FReferenceCollector& Collector)
{
}

//------------------------------------------------------Graph-----------------------------------------------------------

void FluidNarratorGraphEditor::Initalize(const EToolkitMode::Type Mode, const TSharedPtr<IToolkitHost>& InitToolkitHost, UFluidNarratorGraph* InitGraph)
{
Graph = InitGraph;

InitalizeEdGraph();
InitalizePropertyWidget();
InitalizeViewportWidget();

// Layout
const TSharedRef<FTabManager::FLayout> Layout = FTabManager::NewLayout("Fluid_Narrator_Layout")
->AddArea
(
FTabManager::NewPrimaryArea()->SetOrientation(Orient_Vertical)
->Split
(
FTabManager::NewSplitter()->SetOrientation(Orient_Horizontal)->SetSizeCoefficient(0.9f)
->Split
(
FTabManager::NewStack()
->SetSizeCoefficient(0.65f)
->AddTab(FFluidNarratorAssetEditorTabs::ViewportID, ETabState::OpenedTab)->SetHideTabWell(true)
)
->Split
(
FTabManager::NewSplitter()->SetOrientation(Orient_Vertical)
->Split
(
FTabManager::NewStack()
->SetSizeCoefficient(0.7f)
->AddTab(FFluidNarratorAssetEditorTabs::DetailsID, ETabState::OpenedTab)->SetHideTabWell(true)
)
)
)
);


FAssetEditorToolkit::InitAssetEditor(Mode, InitToolkitHost, "Narrator Graph Editor", Layout, false,false, Graph, true);

//CRASHES HERE
EdGraph->CreateNarratorGraphNode(FVector2D(0, 0));
}

void FluidNarratorGraphEditor::InitalizeEdGraph()
{
if (EdGraph == nullptr)
{
EdGraph = CastChecked<UFluidNarratorEdGraph>(FBlueprintEditorUtils::CreateNewGraph(Graph, NAME_None, UFluidNarratorEdGraph::StaticClass(), UFluidNarratorEdGraphSchema::StaticClass()));
EdGraph->bAllowDeletion = false;
const UEdGraphSchema* Schema = EdGraph->GetSchema();
Schema->CreateDefaultNodesForGraph(*EdGraph);
}
}

void FluidNarratorGraphEditor::InitalizeViewportWidget()
{
FGraphAppearanceInfo AppearanceInfo;
AppearanceInfo.CornerText = FText::FromString("Fluid Narrator Graph");

SGraphEditor::FGraphEditorEvents InEvents;
//InEvents.OnSelectionChanged = SGraphEditor::FOnSelectionChanged::CreateSP(this, &FAssetEditor_GenericGraph::OnSelectedNodesChanged);
//InEvents.OnNodeDoubleClicked = FSingleNodeEvent::CreateSP(this, &FAssetEditor_GenericGraph::OnNodeDoubleClicked);

ViewportWidget = SNew(SGraphEditor)
.IsEditable(true)
.Appearance(AppearanceInfo)
.GraphToEdit(EdGraph)
.GraphEvents(InEvents)
.AutoExpandActionMenu(true)
.ShowGraphStateOverlay(false);

//.AdditionalCommands(GraphEditorCommands)
}

void FluidNarratorGraphEditor::InitalizePropertyWidget()
{
FDetailsViewArgs Args;
Args.bHideSelectionTip = true;
Args.NotifyHook = this;
FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
PropertyWidget = PropertyModule.CreateDetailView(Args);
PropertyWidget->SetObject(Graph);
}

//------------------------------------------------------Spawn Tabs-----------------------------------------------------------

TSharedRef<SDockTab> FluidNarratorGraphEditor::SpawnTabViewport(const FSpawnTabArgs& Args)
{
check(Args.GetTabId() == FFluidNarratorAssetEditorTabs::ViewportID);

TSharedRef<SDockTab> SpawnedTab = SNew(SDockTab)
.Label(FText::FromString("Viewport"));

if (ViewportWidget.IsValid())
SpawnedTab->SetContent(ViewportWidget.ToSharedRef());

return SpawnedTab;
}

TSharedRef<SDockTab> FluidNarratorGraphEditor::SpawnTabProperties(const FSpawnTabArgs& Args)
{
check(Args.GetTabId() == FFluidNarratorAssetEditorTabs::DetailsID);

return SNew(SDockTab)
.Icon(FEditorStyle::GetBrush("LevelEditor.Tabs.Details"))
.Label(FText::FromString("Details"))

PropertyWidget.ToSharedRef()
];
}


EGraphType UFluidNarratorEdGraphSchema::GetGraphType(const UEdGraph* TestEdGraph) const
{
return EGraphType();
}

void UFluidNarratorEdGraphSchema::GetGraphContextActions(FGraphContextMenuBuilder& ContextMenuBuilder) const
{
}

void UFluidNarratorEdGraphSchema::GetContextMenuActions(UToolMenu* Menu, UGraphNodeContextMenuContext* Context) const
{
}

const FPinConnectionResponse UFluidNarratorEdGraphSchema::CanCreateConnection(const UEdGraphPin* A, const UEdGraphPin* B) const
{
return FPinConnectionResponse();
}

bool UFluidNarratorEdGraphSchema::CreateAutomaticConversionNodeAndConnections(UEdGraphPin* A, UEdGraphPin* B) const
{
return false;
}

FConnectionDrawingPolicy* UFluidNarratorEdGraphSchema::CreateConnectionDrawingPolicy(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements, UEdGraph* InGraphObj) const
{
return nullptr;
}

FLinearColor UFluidNarratorEdGraphSchema::GetPinTypeColor(const FEdGraphPinType& PinType) const
{
return FLinearColor();
}

void UFluidNarratorEdGraphSchema::BreakNodeLinks(UEdGraphNode& TargetNode) const
{
}

void UFluidNarratorEdGraphSchema::BreakPinLinks(UEdGraphPin& TargetPin, bool bSendsNodeNotifcation) const
{
}

void UFluidNarratorEdGraphSchema::BreakSinglePinLink(UEdGraphPin* SourcePin, UEdGraphPin* TargetPin) const
{
}

UEdGraphPin* UFluidNarratorEdGraphSchema::DropPinOnNode(UEdGraphNode* InTargetNode, const FName& InSourcePinName, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection) const
{
return nullptr;
}

bool UFluidNarratorEdGraphSchema::SupportsDropPinOnNode(UEdGraphNode* InTargetNode, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection, FText& OutErrorMessage) const
{
return false;
}

bool UFluidNarratorEdGraphSchema::IsCacheVisualizationOutOfDate(int32 InVisualizationCacheID) const
{
return false;
}

int32 UFluidNarratorEdGraphSchema::GetCurrentVisualizationCacheID() const
{
return int32();
}

void UFluidNarratorEdGraphSchema::ForceVisualizationCacheClear() const
{
}




void UFluidNarratorEdGraphNode::AllocateDefaultPins()
{
}

FText UFluidNarratorEdGraphNode::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
return FText::FromString("Fluid Narrator Node");
}

FText UFluidNarratorEdGraphNode::GetTooltipText() const
{
return FText();
}



UFluidNarratorEdGraph::UFluidNarratorEdGraph()
{

}

UFluidNarratorEdGraph::~UFluidNarratorEdGraph()
{
}

void UFluidNarratorEdGraph::RebuildGenericGraph()
{
}

bool UFluidNarratorEdGraph::Modify(bool bAlwaysMarkDirty)
{
return false;
}

void UFluidNarratorEdGraph::PostEditUndo()
{
Super::PostEditUndo();
NotifyGraphChanged();
}

void UFluidNarratorEdGraph::CreateNarratorGraphNode(const FVector2D Location)
{
UEdGraphNode* NewNode = NewObject<UFluidNarratorEdGraphNode>();
if (NewNode != nullptr)
{
NewNode->NodePosX = Location.X;
NewNode->NodePosX = Location.Y;
AddNode(NewNode);
}
}


Here is the crash log. Not sure what “GetOuter” is.

Ok I fixed it. Here is my new code for Create Node


UEdGraphNode* NewNode = NewObject<UFluidNarratorEdGraphNode>(this);
if (NewNode != nullptr && NewNode->GetOuter() != nullptr && Schema != nullptr)
{
Modify();
NewNode->SetFlags(RF_Transactional);
NewNode->Rename(NULL,this, REN_NonTransactional);
NewNode->CreateNewGuid();
NewNode->NodePosX = Location.X;
NewNode->NodePosY = Location.Y;
NewNode->SnapToGrid(10);
NewNode->AllocateDefaultPins();
AddNode(NewNode);
}