Access Blueprint Function Library in C++

Hi quys,

I have a Blueprint Function Library BFL_Test created in Blueprint with a public method PublicMethod. Is it possible to access BFL_Test->PublicMethod from a C++ class?

Thanks

Yes: BFL_Test::PublicMethod( ... ).

All functions in a function library should be static, so you have to call them that way (with the :: scope operator instead of with -> using an instance of the class).

2 Likes

I have tried that, but Cpp file doesn’t regcognised BFL_Test


BFL_2

Don’t trust highlights or squiggle underlines, provide compiler errors.

But if I had to hazard a guess, you probably just haven’t included the header file for your function library class.

Hi, you can use the “FindFunction()” method in AActor to find it in the dictionary, then call it if found: (the CallInEditor must be ticked)

UFunction* func=MyActor->FindFunction(FName(TEXT("Public Method")));
if(func) {
	MyActor->ProcessEvent(func,nullptr);
}
1 Like

This is absolutely terrible advice. There is no reason to call a C++ function from C++ code using ProcessEvent.

I think OP’s BFL is created in Editor, not C++. So PublicMethod is not a C++ function.

On that note, why not just create the BFL in C++? If you want to implement the function in Blueprint, you can use BlueprintImplementableEvent or BlueprintNativeEvent UFUNCTION specifiers.

1 Like

Yeah, you’re absolutely right. Sorry @RecourseDesign and @peterhuynh_2904, I completely missed those two very important words in the original post.

@peterhuynh_2904 If you want to be able to call your function library function from C++, you’ll have to make your function library in C++.

You can’t mix-n-match function libraries like you can other objects. I quickly tried out @Extrone’s suggestion because it seemed suspicious, and verified that you can’t do BlueprintImpementableEvent or BlueprintNativeEvent with function libraries because that markup doesn’t work (and is nonsensical) for static functions. It causes compiler errors (though UHT should catch this way earlier).

However @peterhuynh_2904’s option won’t work either because it requires you to have access to an instance of the class with the function to call ProcessEvent on it. And you can’t easily get an instance of a function library object because they don’t really exist. It’s not impossible to accomplish, but it’s more work than it needs to be and isn’t how you should do things in this engine.

That brings us back to: if you want to access the functions of a function library from C++, you’ll have to write it in C++.

2 Likes

Thanks all. Look like it’s best to re-write the function in C++. I followed a tutorial that using Blueprint and wanted to continue using C++.

I was running in to a couple BP->C++ issue and this is one of the one I couldn’t figured out :frowning: Using C++ function is :+1: but BP function in C++ :-1:

You can get an instance for function libs, it’s the class default object.

I also tried various attempts at creating an intermediate C++ BFL with an override-able/implementable BP function, but no luck so far.

A simpler way would be to turn functions into member functions, and provide an accessor. No need to manage an instance since there’s already the CDO. You just need a variable somewhere to hold a reference to the BP version of the lib.
For example

UCLASS(Blueprintable, Abstract)
class UBFL_Test : public UObject
{
    GENERATED_BODY()

    UPROPERTY()
    UClass* BpLibClass;

    UBFL_Test()
    {
        static ConstructorHelpers::FClassFinder<ThisClass> BpLibAsset(TEXT("/Game/BP_BFL_Test"));
        if (BpLibAsset.Succeeded())
        {
            BpLibClass = BpLibAsset.Class;
        }
    }

public:
    UFUNCTION(BlueprintPure)
    static ThisClass* Get() { return BpLibClass->GetDefaultObject<ThisClass>(); }

    UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
    void PublicMethod();
};

The referenced asset at /Game/BP_BFL_Test would be a blueprint child class of UBFL_Test which implements the methods.

Of course it would be better to reference it in a BP-assignable variable such as in a GameInstance subclass. FClassFinder is more of a prototyping temporary solution.

You could even make a wrapper for each function to make it entirely transparent for the blueprints side, but that might get quickly cumbersome, like so

UFUNCTION(BlueprintImplementableEvent) //not callable
void PublicMethodImpl();

UFUNCTION(BlueprintCallable)
static void PublicMethod() { return Get()->PublicMethodImpl(); }