Copy/Pasting custom editor nodes between projects

The issue was posted by me at this thread back in March, but it took me some time before I could get to my issue once more.

Looks like previous thread contained too few useful information for possible solution, so I’ll try to me more precise right now.

I’ve made a custom editor and bunch of custom nodes, but I can’t copy/paste them between projects (copy node from editor in one project to editor of other projects).
After making some comparison between Behavior Tree Editor (I’ll call it BTE) and my tool I’ve figured out the issue, but still can’t find a solution for it.

To be able to operate at runtime custom node should have it’s runtime instance, that would contain all required information about node and keep it at runtime.
When making Copy (Ctrl+C) of BTE node I usually get an UnrealScript snippet similar to this one:
(I’ve deleted some stuff that is not related to Runtime Instance like node position, guid, node pin properties and other stuff.)


Begin Object Class=BehaviorTreeGraphNode_Task Name="BehaviorTreeGraphNode_Task_4"
   Begin Object Class=BTTask_MakeNoise Name="BTTask_MakeNoise_4"
   End Object
   NodeInstance=BTTask_MakeNoise'BTTask_MakeNoise_4'
End Object

while UnrealScript of my node looks like this:


Begin Object Class=DialogueConduitNode Name="DialogueConduitNode_1"
   NodeRuntimeInstance=DialogueConduitNodeRuntime'DialogueConduitNodeRuntime_1'
End Object

As expected, copying BTE node from one project’s to another project’s editor goes just fine, while copying of my node ends up with error.
I’ve manually added similar to BTE’s snippet lines to make mine look like this:


Begin Object Class=DialogueConduitNode Name="DialogueConduitNode_1"
   Begin Object Class=DialogueConduitNodeRuntime Name="DialogueConduitNodeRuntime_1"
   End Object
   NodeRuntimeInstance=DialogueConduitNodeRuntime'DialogueConduitNodeRuntime_1'
End Object

And now copy/paste works pretty well, so the problem is when I make copy


   Begin Object Class=DialogueConduitNodeRuntime Name="DialogueConduitNodeRuntime_1"
   End Object

stuff is not generated.

Source of AIGraphNode can be seen here, but for me looks like important stuff should be seen in the header:


UCLASS()
class AIGRAPH_API UAIGraphNode : public UEdGraphNode
{
	GENERATED_UCLASS_BODY()

	/** instance class */
	UPROPERTY()
	struct FGraphNodeClassData ClassData;

	UPROPERTY()
	UObject* NodeInstance;

....

while mine looks like this:


UCLASS()
class DIALOGUETOOLEDITOR_API UDialogueNodeBase : public UEdGraphNode
{
	GENERATED_BODY()

public:

	UPROPERTY()
		UDialogueNodeBaseRuntime* NodeRuntimeInstance;

	UPROPERTY()
		UClass* NodeRuntimeClass;

...

Are there any specific methods that should be used to generate Begin Object Class?

I’ve tried to dig a bit deeper and found out that parent UObject that has another UObject inside (inner object) gets to FExportObjectInnerContext list and is kept persistent through it’s runtime.
When node copy is happening, parent object is getting export to text, after that it’s inner objects are found in FExportObjectInnerContext and also getting exported.
However, I still can’t find set of methods that would help me to get inner objects linked to it’s parent and get all stuff to FExportObjectInnerContext.

Issue solved.

When looking into FExportObjectInnerContext constructor I’ve found out it’s iteration through objects and making referencing map with (duh!) UObject::GetOuter()
I’ve looked up for my node and turned out I’ve set custom graph as owner of RuntimeNode instead of actual UEdGraphNode.

In short - me being very absent-minded and doing this
(in UDialogueNodeBase which is UEdGraphNode derived)


NodeRuntimeInstance = NewObject<UDialogueNodeBaseRuntime>(MyGraph, NodeRuntimeClass);


Instead of this


NodeRuntimeInstance = NewObject<UDialogueNodeBaseRuntime>(this, NodeRuntimeClass);