Migrating custom nodes / assets between projects.

I’m having an amazing amount of help from forum users every time I’m getting lost, so I dare to ask for help once more :slight_smile:
I’ve finished a custom asset type for editor and was pretty happy with it until a migrating from test project to a real one required. Turned out copy and pasting nodes from one project to another requires some work.

As for copying nodes:
My custom node have a


UObject* RuntimeNodeInstance

that holds all necessary data and can be used in game. Now when I copy the node from one project’s editor to another project’s editor, it doesn’t copy any of RuntimeNodeInstance’s data nor it allocates memory for it.
There is nothing tricky to create an object for a node, but how can I transfer required data?
I’ve inspected import text from BehaviourTreeEditor and there are few lines my import text node doesn’t have.

My node:


Begin Object Class=DialogueExpressionNode Name="DialogueExpressionNode_9"
   NodeRuntimeInstance=DialogueExpressionNodeRuntime'DialogueExpressionNodeRuntime_3'
   NodeRuntimeClass=Class'/Script/DialogueTool.DialogueExpressionNodeRuntime'
...

BehaviourTreeEditor node:


Begin Object Class=BehaviorTreeGraphNode_SimpleParallel Name="BehaviorTreeGraphNode_SimpleParallel_0"
   Begin Object Class=BTComposite_SimpleParallel Name="BTComposite_SimpleParallel_1"
   End Object
   Begin Object Name="BTComposite_SimpleParallel_1"
      TreeAsset=BehaviorTree'/Game/NewBehaviorTree.NewBehaviorTree'
   End Object
   ClassData=(ClassName="BTComposite_SimpleParallel")
   NodeInstance=BTComposite_SimpleParallel'BTComposite_SimpleParallel_1'
...

So BehaviourTreeEditor somehow transfers data about runtime object, about it’s location and class. I guess this data is used to spawn a runtime object upon copy, but how can that be achieved?

Also I did want to copy custom .uasset from one project to another and it’s getting copied and recognized correctly, but I can’t open it.
I just click it and nothing happens at all. FAssetTypeActions_Base::OpenAssetEditor() should get called, but just nothing happens.
On right click editor says “Failed to load Asset”. I guess it’s linked with the first trouble.

You need to show more code for your custom node/asset type. It’s not even clear which it is you’ve created.

Both node and asset are not sophisticated.

Here’s header of node base class.



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

public:

	UPROPERTY()
		UDialogueNodeBaseRuntime* NodeRuntimeInstance;

	UPROPERTY()
		UClass* NodeRuntimeClass;

	bool IsPositionFixed = true;
	SGraphNode* NodeWidget;

	virtual void SetRuntimeClass();
	virtual void PostPlacedNewNode();

};

I’ve removed unnecessary methods like DoubleClick(), AutoWireNewNode() and other.
NodeRuntimeInstance is an object holding all kind of data that should present in game (text, sound, conditions and others)
NodeRuntimeClass is a class name of runtime node. It is used to spawn correct instance for specific node in PostPlacedNewNode();

like this


void UDialogueNodeBase::SetRuntimeClass()
{
	NodeRuntimeClass = UDialogueNodeBaseRuntime::StaticClass();
}

void UDialogueNodeBase::PostPlacedNewNode()
{
	SetRuntimeClass();
	UEdGraph* MyGraph = GetGraph();
	UObject* GraphOwner = MyGraph ? MyGraph->GetOuter() : nullptr;
	if (GraphOwner)
	{
		NodeRuntimeInstance = NewObject<UDialogueNodeBaseRuntime>(GraphOwner, NodeRuntimeClass);
		NodeRuntimeInstance->SetFlags(RF_Transactional);
	}
}

That’s about it! The main part is slate there, so uobject functionality is minimal.
When spawning new node PostPlacedNewNode() is called and runtime instance is created. When node is copied, two copies share same RuntimeInstance so I call PostPlacedNewNode() once more and duplicate object data. In that way I have two objects with same data but different RuntimeInstances.

Problem is when I copy data from one project to another it has no idea about RuntimeInstance it’s pointing to. I guess here comes the trouble, no luck transfering UObject data in text copy
(which i do with these


	FEdGraphUtilities::ExportNodesToText(SelectedNodes, /*out*/ ExportedText);
	FPlatformMisc::ClipboardCopy(*ExportedText);

)


Asset is even more simple


UCLASS(Blueprintable)
class MUSICGAME_API UDialogueAsset : public UObject
{
	GENERATED_BODY()
public:

	UPROPERTY(BlueprintReadWrite)
		class UDialogueNodeBaseRuntime* TreeStartNode; //node the tree starts with. Containing children nodes.

#if WITH_EDITORONLY_DATA
	UPROPERTY()
	UEdGraph* DialogueEditorGraph; 
#endif //WITH_EDITORONLY_DATA

};

It is created with FactoryCreateNew() and nothing else is implemented to spawn an asset.