Is it possible to call a blueprint function from python?

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);
            }
        }
    }
}

Did you ever find anything for this? I’m now trying to do the same thing in python, but after a very thorough dig through the docs I’ve drawn a blank…

At this time, python does not have access to blueprint functions, but it does have access to your C++ methods.
So, the solution is to declare your blueprint function in C++ as a BlueprintImplementableEvent, and then override it in your blueprint.

I’d recommend checking it works by calling your BlueprintImplementableEvent from C++ before you move on.
Next, make a secondary C++ function to call your BlueprintImplementableEvent.
This function must be implemented as a BlueprintCallable, as these are the ones that are exposed to python.

Finally, once your C++ and blueprints are compiled, all you need to do is call your caller function from python;
your C++ class will be visible as a normal C++ module like so: unreal.YourClassName.yourCallerFunctionName(yourClassInstance, args)
Arguments and return values are handled exactly as you’d expect.
You must pass your function the class instance you wish the function to run from. Very useful when manipulating specific AActor instances.


One final note; if you need your function to be implemented as a blueprint function rather than a blueprint event like I did, you must either make your function constant or give a return value (even if you don’t use it). Otherwise, it will appear in your blueprint overrides as an event.

Screens from my use case, obviously the specifics of my blueprint function implementation is irrelevant:
Blueprint function


.h
Header file declaring my c++ functions (see image)
.cpp
Implementation of my caller utility function (see image)
.py
My python code calling the caller function (see image)

Error in my .py screenshot. The first line should read:
if unreal.planeTrackEditableWrapper.call_clear_spline(actor)
You may infer from this and my C++ code that planeTrackEditableWrapper is the name of the class containing my blueprint interfacing functions, which is also the parent of my blueprint class.
Probably should have mentioned the class parenting part as that lets your C++ talk to the blueprint, let me know if you need to hear about that.

Hello!

Here is a snippet demonstrating how to do that in a simple way, without any C++.
Call functions or modify properties of a Blueprint from Python | Epic Developer Community (epicgames.com)

1 Like

You need to do:

  • Wrap a function in another function
  • Expose inputs in args/kwargs.

In my example I wrapped AddMeshSections function in AddMeshSectionsPy function.
After that I called this function from Python:

my_actor.call_method("AddMeshSectionsPy", args=(my_array, ))

1 Like