-
Notifications
You must be signed in to change notification settings - Fork 33
Adding a function
HiIAmMoot edited this page May 1, 2020
·
4 revisions
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;
};