Fix hard crash in SpawnActor node creation

UK2Node_SpawnActorFromClass::PostPlacedNewNode() (engine source)
overrides the base class without calling Super::PostPlacedNewNode(),
and unconditionally dereferences GetScaleMethodPin() via
FindPinChecked -- but that pin is only created in
AllocateDefaultPins(), which FGraphNodeCreator::Finalize() always
calls *after* PostPlacedNewNode(). Result: a hard assertion failure
(EdGraphNode.h:586) that crashes the whole editor, every time,
regardless of any node_json parameters.

The real editor UI never hits this because it creates nodes through
a different path (node spawner templates) that doesn't have this
ordering problem. Our plugin uses the generic FGraphNodeCreator
pattern directly, so it does.

Fix: manually call SpawnNode->AllocateDefaultPins() before
Creator.Finalize(), so pins already exist by the time
PostPlacedNewNode() runs. Verified: SpawnActor node now creates
cleanly with all expected pins (Class, SpawnTransform, etc), editor
stayed stable and MCP connection alive afterward.

Rebuilt via Live Coding successfully this time (Ctrl+Alt+F11) --
the earlier UbaCli spawn failure appears to have been a one-off,
possibly from a conflicting concurrent Build.bat invocation.
This commit is contained in:
Joshua Deville
2026-07-08 22:33:50 -04:00
parent 58794dbd25
commit 226a979d66

View File

@@ -645,6 +645,13 @@ static UEdGraphNode* CreateBPNodeFromJson(UEdGraph* Graph, UBlueprint* Blueprint
UK2Node_SpawnActorFromClass* SpawnNode = Creator.CreateNode(false); UK2Node_SpawnActorFromClass* SpawnNode = Creator.CreateNode(false);
SpawnNode->NodePosX = PosX; SpawnNode->NodePosX = PosX;
SpawnNode->NodePosY = PosY; SpawnNode->NodePosY = PosY;
// Engine bug workaround: UK2Node_SpawnActorFromClass::PostPlacedNewNode() does not call
// Super::PostPlacedNewNode() and unconditionally dereferences GetScaleMethodPin() via
// FindPinChecked, but that pin is only created in AllocateDefaultPins(). FGraphNodeCreator::
// Finalize() always calls PostPlacedNewNode() before AllocateDefaultPins(), so on this node
// type it hard-crashes (assert) unless pins already exist beforehand. The real editor UI
// avoids this node-creation path entirely; we can't, so pre-allocate pins ourselves.
SpawnNode->AllocateDefaultPins();
Creator.Finalize(); Creator.Finalize();
NewNode = SpawnNode; NewNode = SpawnNode;
} }