I found this answer that explains how to inspect blueprint functions, but I can’t find anything about calling blueprint functions from python. It looks like I would need to pass void* params from python to c++ in order to pass arbitrary parameters. It looks like I can create a bridge for specific functions, but calling arbitrary functions is impossible. Am I wrong? Is there a way to do this?
This is what I’ve got so far:
UFUNCTION(BlueprintCallable)
static void FindBlueprintFunctions(UObject* Asset);
// This doesn't compile. void* Params is obviously not a valid type
UFUNCTION(BlueprintCallable)
void CallBlueprintFunctions(UObject* Asset, FString FunctionName, void* Params)
.
// This runs, but doesn't return anything yet.
void FindBlueprintFunctions(UObject* Asset)
{
if (Asset)
{
UBlueprint* BlueprintObject = Cast<UBlueprint>(Asset);
if (BlueprintObject && BlueprintObject->GeneratedClass)
{
for (TFieldIterator<UFunction> It(BlueprintObject->GeneratedClass); It; ++It)
{
UFunction* Func = *It;
UE_LOG(LogTemp, Warning, TEXT("Function Name: %s"), *Func->GetName());
auto& PropertyLink = Func->PropertyLink;
while (PropertyLink != nullptr)
{
if (PropertyLink && (PropertyLink->GetPropertyFlags() & CPF_ReferenceParm) == 0)
{
FString ParamName = PropertyLink->GetName();
FString ParamType = PropertyLink->GetCPPType(NULL, CPPF_None);
UE_LOG(LogTemp, Warning, TEXT(" Parameter: %s - %s"), *ParamName, *ParamType);
}
PropertyLink = PropertyLink->PropertyLinkNext;
}
}
}
}
}
UFunction* FindBlueprintFunction(UBlueprint BlueprintObject, FString FunctionName)
{
if (BlueprintObject && BlueprintObject->GeneratedClass)
{
for (TFieldIterator<UFunction> It(BlueprintObject->GeneratedClass); It; ++It)
{
UFunction* Func = *It;
if (Func->GetName() == FunctionName)
{
return Func;
}
}
}
return nullptr;
}
void CallBlueprintFunctions(UObject* Asset, FString FunctionName, void* Params)
{
if (Asset)
{
UBlueprint* BlueprintObject = Cast<UBlueprint>(Asset);
if (BlueprintObject && BlueprintObject->GeneratedClass)
{
UFunction* Function = FindBlueprintFunction(BlueprintObject, FunctionName);
if (Function)
{
BlueprintObject->ProcessEvent(Function, Params);
}
}
}
}