Download

Calling UFUNCTION in UObject-derived base class from blueprint editor.

I am making a custom editor and implemented some nodes in it.

Here is the definition of such node:


class TESTTOOL_API UCustomNodeBase : public UEdGraphNode 

with a regular UFUNCTION defined inside:


UFUNCTION(BlueprintCallable, Category = "Some basic stuff")
void BasicStuff() {};

Let’s say I have this node placed in the custom editor. Now let’s say I have an actor which have an access to this node (obtained with CustomGraph->GetNodesOfClass()) and want to access UFUNCTION or UPROPERTY of this node from regular blueprint.

The problem is I can’t see them in regular blueprint but the rest of UObject-derived classes gives visibility of UFUNCTION and UPROPERTY pretty well.

tl;dr

UEdGraphNode derived classes UFUNCTIONs are not showing in blueprints.
Other UObject derived classes (for example UBlueprintFunctionLibrary) UFUNCTIONs are showing in blueprints.
Why is that so?

I’m using a 4.14.3 version of engine

A little update. A problem is still here, but I’ve picked up some more data on issue.
Turns out you CAN use UEdGraphNode’s UPROPERTY and UFUNCTION definitions in blueprints, but you can’t have an access to them in context menu.
Looks like it just doesn’t get captured by reflection system.
I’ve derived blueprint from C++ UEdGraphNode class and added the function with the same name as in C++.
System alerted me that such function exists and base function appeared in Functions tab. I was able to drag it and use in other blueprints.
This workaround, however, can’t be used with UPROPERTY in same way since you can’t provoke variable to throw an override alert.

So yeah, here’s the issue, some UObject-derived classes doesn’t get their UPROPERTYs and UFUCTIONs in reflection system. Is there way to modify UEdGraphNode to register U-stuff in reflection system?

Hi, I think it is something like this:




void MyBPLIB::CallFunctionNameWithArg(UObject* Object, FString FunctionName, FLinearColor color)
{
	FName const FunctionFName(*FunctionName);

	if (Object)
	{
		UFunction* const Func = Object->FindFunction(FunctionFName);
		if (Func && (Func->ParmsSize > 0))
		{
			FTimerDelegate Delegate;
			Delegate.BindUFunction(Object, FunctionFName, color);
			Delegate.Execute();
			return;
		}
	}

	GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Red, "fail");
}


That looks like good workaround and I hope costs of FindFunction() would be minimal.
However I’ve found another workaround as well.

Here’s an example of accessing UPROPERTY inside of blueprint derived class.


Begin Object Class=K2Node_VariableGet
    VariableReference=(MemberName="BasicStuff",bSelfContext=True)
 End Object

and the one for accessing UPROPERTY from another BP


Begin Object Class=K2Node_VariableGet
    VariableReference=(MemberParent=Class'/Script/TestTool.CustomNodeBase',MemberName="BasicStuff")
 End Object

I’m simply pasting snippet into blueprint editor.
Accessing UFunctions works in the same way.

It’s not clear exactly what the problem is. Maybe because the class doesn’t have the BlueprintType UCLASS specifier?

But more to the point, what you’re trying to do doesn’t seem to make sense. UEdGraphNodes only exist within the editor. They are a tool for providing a node based editor, but they won’t exist in a packaged game so it doesn’t make sense to want to access them via Blueprint.

The UCLASS is being marked as Blueprintable.
I didn’t know UEdGraphNodes stops existing in packaged game.
That rises few very important questions for me.
Let’s say I have a bunch of nodes inside of custom editor and each node has an important information that should exist in game.
I also have a UCustomAsset which holds UEdGraph reference and responsible for storing custom editor data.
It turns I can’t use UCustomAsset data in packaged game as well? How can I access node data in game?
Can I somehow copy data from UEdGraphNode to UObject without touching UEdGraphNode at runtime?

Blueprintable is not the same as BlueprintType - it’s the latter which controls whether or not a class can be accessed from a Blueprint graph.

Your UEdGraph property should be enclosed in a #if WITH_EDITORONLY_DATA preprocessor block. You need to set up your asset editor so that when the asset is saved, the ed graph is processed and all runtime-relevant data is stored in other (not editor-only) properties of your asset. Often this will mean having two parallel sets of node types - UMyCustomNode (runtime) and UMyCustomEdGraphNode (editor, derived from UEdGraphNode). Check out the behavior tree editor in the engine for an example. The approach there is to make the ed graph nodes just wrap a runtime node - they add on the editor-specific functionality, then when the asset is saved the internal nodes are used to build up a runtime version of the behavior tree, which is stored on the asset.

That was an extremely helpful post, looks like I were really going the wrong way.
Thank you, sir.