How can I allow a method to be overridden in both blueprints and C++?

you can explain why you need to make event is virtual

You can explain what you meant, since I’m having trouble understanding your comment.

Oh, cool! So, to clarify, I shouldn’t use BlueprintImplementableEvent at all? Even if there’s no sensible native implementation? Should I just add a throw SomeException("you called a method that should never be called"); line to the DoAThing_Implementation method in the base class?

I have a class defined in C++. It has a method:

UFUNCTION(BlueprintNativeEvent)
void DoAThing();

This is great if I want to override it in blueprints. It’s not so great if I want to override it in C++. When I try to add virtual:

UFUNCTION(BlueprintNativeEvent)
virtual void DoAThing();

I get a compile error:

BlueprintNativeEvent functions must be non-virtual

I’m trying to do the same thing with “pure virtual” (i.e. using PURE_VIRTUAL) functions using BlueprintImplementableEvent, and I’m getting this error with that:

BlueprintImplementableEvents should not be virtual. Use BlueprintNativeEvent instead.

…except, as we saw, that doesn’t work, either.** How can I get Unreal to let me override a function in both C++ and blueprints?**

I’d like to do this because the DoAThing() implementations might get quite expensive, both in terms of performance and maintenance, and I’d like to be able to move code from C++ to blueprints. I also have team members who prefer using C++ to blueprints, and would like to accommodate them as much as possible.

BlueprintNativeEvent is correct. The method you define is the stub, there is then an implementation method, which is virtual. I don’t remember if it gets auto declared, but anyway you can do so yourself:
virtual void DoAThing_Implementation();
You can provide the implementation in that class, and/or implement it in derived C++ classes, and/or in blueprints.

Use BlueprintImplementableEvent if you just want an optional blueprint-only notify, which you don’t care if someone doesn’t bother implementing.

Otherwise, yeah BlueprintNativeEvent is more flexible, and if it’s mandatory that it gets implemented at some level, then yeah you want some check. UE4 generally doesn’t use exceptions, and you don’t want to crash the editor whenever someone forgets to implement something. So put something like ensureMsg(false, ...) which will break if you’re debugging, and also print an error to the output log.

1 Like

Guide by Rama