Adding a function - HiIAmMoot/RuntimeBPs GitHub Wiki

Adding a function

To add a new function, one needs to make a derived class of RuntimeBpObject. Take a look at ExampleNodes.h and ExampleNodes.cpp as a base for making a new function. Each funtion generally overrides the constructor and the Execute function. The constructor contains your general function info like name, category, description etc. Your input and output pins are defined here as well. In case you have a big list of functions you don't want to convert by hand, you can use the FunctionConverter python script to convert existing UE4 libraries and other classes like Actor.

Here's an example for a simple if statement.

// .cpp

UBranch::UBranch()
{
	NodeName = "Branch";
	NodeCategory = "Flow Control";

	InputPins.SetNum(2);
	InputPins[0].MakeNodePin();// No args means execute

	InputPins[1].MakeNodePin("Condition", EVariableTypes::Bool);
	InputPins[1].Value.Array[0].SetBoolArg(true); // Default value

	OutputPins.SetNum(2);
	OutputPins[0].MakeNodePin("True");
	OutputPins[1].MakeNodePin("False");

}

void UBranch::Execute(int Index, int FromLoopIndex)
{
	if (GetConnectedPinValue(InputPins[1]).GetBoolArg())
	{
		Super::Execute(0, FromLoopIndex);// 0 here is the output pins array index
	}
	else
	{
		Super::Execute(1, FromLoopIndex);// 1 here is the output pins array index
	}
}
// .h

UCLASS()
class RUNTIMEBLUEPRINTS_API UBranch : public URuntimeBpObject
{
	GENERATED_BODY()

public:

	UBranch();

	virtual void Execute(int Index, int FromLoopIndex = -1) override;

};

Here's an example when dealing with arrays.

// .cpp

UGetAllActorsOfClass::UGetAllActorsOfClass()
{
	NodeName = "Get All Actors Of Class";
	NodeCategory = "Utilities";

	InputPins.SetNum(2);
	InputPins[0].MakeNodePin();// No args means execute

	InputPins[1].MakeNodePin("Actor Class", EVariableTypes::Class);
	InputPins[1].Value.Array[0].SetClassArg(); // Default value

	OutputPins.SetNum(2);
	OutputPins[0].MakeNodePin("Then");
	OutputPins[1].MakeNodeArray("Out Actors", EVariableTypes::Actor);

}

void UGetAllActorsOfClass::Execute(int Index, int FromLoopIndex)
{
	TSubclassOf<AActor> ActorClass = GetConnectedPinValue(InputPins[1]).GetClassArg();
	if (ActorClass)
	{
		if (BPConstructor->GetMultiThread())
		{
			// We must execute the actual spawning inside the GameThread, a crash will occur otherwise
			AsyncTask(ENamedThreads::GameThread, [this, ActorClass, FromLoopIndex]()
			{
				UGameplayStatics::GetAllActorsOfClass(this, ActorClass, OutActors);
				OutputPins[1].Value.SetActorArg(OutActors);
				URuntimeBpConstructor::Thread->ContinueExecute(BPConstructor, NodeIndex, 0, FromLoopIndex, FunctionIndex);
			});
		}
		else
		{
			UGameplayStatics::GetAllActorsOfClass(this, GetConnectedPinValue(InputPins[1]).GetClassArg(), OutActors);
			OutputPins[1].Value.SetActorArg(OutActors);
			Super::Execute(0, FromLoopIndex);// Index here is the output pins array index
		}
	}
	else
	{
		Super::Execute(0, FromLoopIndex);// 0 here is the output pins array index
	}
}
// .h

UCLASS()
class RUNTIMEBLUEPRINTS_API UGetAllActorsOfClass : public URuntimeBpObject
{
	GENERATED_BODY()

public:

	TArray<AActor*> OutActors;

	UGetAllActorsOfClass();

	virtual void Execute(int Index, int FromLoopIndex = -1) override;
};
⚠️ **GitHub.com Fallback** ⚠️