Using BlueprintNativeEvent with Inheritance for Blueprint and Cpp Configurable Functions

Shahriar Shahrabi
7 min readMay 15, 2020

Using BlueprintNativeEvent and inheritance to create a function that can be partially defined in C++ and partially in Blueprint. Using this setup you can create a rather simple Component system for sharing the same behavior between several Actors.

This post is one of my documentation posts. It is written quite fast and is not structured similar to my other posts.

The blueprint/ C++ system in Unreal Engine is a very powerful tool. For our latest project, I set out with the task of coming up with a system that fulfills two criteria. Firstly we wanted to have behaviours that are shared between several actors, which also hold per instance information. We didn’t want to have the code for the behaviour duplicated, as an Unreal Interface would enforce. We also wished to avoid writing the behaviour in a centralized control actor.

Second, we wanted to be able to define the functions body both in C++ and Blueprint, and have a system where you can easily move code from C++ and Blueprint. The reason why we had the second requirement, was to make sure that all team members can contribute to the coding of interactions.

To solve the first problem, an obvious solution is inheritance. If your first behaviour is Pullable, and the second is Grabable you derive your ExampleObject class from Pullable and Grabable. Then as your controller interacts with your ExampleObject, it could check if it can be casted to Pullable using the Unreal’s reflection system and if yes call a function such as Pull.

The issue with the method above is, that we wanted to be able to partially define the body of the function Pull in Blueprint and partially in C++. To my knowledge C++ classes can not have Blueprint classes as a base. Since ExampleObject itself is a C++ class which will be used as a base for a blueprint class, it can not derive from Pullable class if Pullable is a blueprint class. If we want Pullable to contain Blueprint logic, then it must be a Blueprint class.

The reason why I say “to my knowledge”, is that this is C++. Given unlimited time, people can do whatever they want. So you never know what you find out there.

There are different ways of implementing the above. I am going to mention the way I came up with at the end. You might want to adjust it for your use case.

BlueprintNativeEvent

Blueprint native Events are functions you can declare in your C++ file, which can be defined in Blueprint. In other words you say it exists in C++ and you define what happens once they are called in the Blueprint that derives from this C++ class. They are super useful for various reasons. The relevant one here is that they can call a base implementation of themselves which has been defined in the C++ file. This means you could have the code for that function partially in Blueprint and partially in C++.

The way it works is you declare your function with the UFUNCTION macro above it in the header file of your class:

UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = “Ini”)void Start ();

Then on the Blueprint side, you can define a body for this function like this:

Sofar so good. Now if you want to have a base implementation in the C++ file too, you can define a body for a function that has your function name plus a _Implementation at the end. The Unreal’s system goes through this, and connects this function to your Blueprint version of it. So in your C++ file you can have:

void ABehaviour::Start_Implementation(){GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("This is an on screen message!"));
}

Behaviour is the class I am working with as my base class. Then in the Blueprint side, to call the Start_Implementation, you can call:

This will call the _Implementation first, before executing the rest of the Blueprint code.

Now once you call the Start function, you will see both messages on screen.

Inheritance

I had to struggle a bit for this one. It was not very clear to me at the beginning how the virtual functions work together with the UFUNCTION signature. Turns out it is actually quite simple, you do have to rethink the first solution that might come to you though.

If you inherit from the Behaviour class now, you would want to have your own version of _Implementation for the Start function. However since the Start function is marked with UFUNCTION, it can not be a virtual function, hence you can not override it in a base class.

The trick is, you don’t override your Start function, but your Start_Implementation function. So I created a Class called MoveUpCpp, which I will use to move the actor Up. This derives from Behaviour. What I want in this class is a version of the Start function without the UFUNCTION macro above it and a virtual override version of my Start_Implementation function. You need to leave out the UFUNCTION, since Unreal will realize on its own that Start is related to the Start in the parent, and automatically give it the same attributes as whatever you defined for it in the base class.

So in my base class header, Behaviour I have:

UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = “Ini”)void Start ();virtual void Start_Implementation();

In the Behaviour C++ file I have:

void ABehaviour::Start_Implementation(){}

Now in the MoveUpCpp class, which derives from Behaviour, I have in the header file:

void Start ();virtual void Start_Implementation() override;

And in the C++ file:

void AMoveUpCpp::Start_Implementation(){}

I would have loved to have Behaviour::Start_Implementation on the Start_Implementation of MoveUpCpp, however that results in recursion. I am sure there is something there I am missing, but I haven’t looked deep in to it since it is not required for my use case.

Like this, if you have an instance of MoveUpBP, which would be the blueprint class you derived from the MoveUpCpp, you could call this Start function, which is partially defined in C++ and partially in Blueprint. You could have the reference of this class as a Behaviour or a MoveUpCpp or MoveUpBP and still call the same Start function.

You might ask yourself why all the gymnastic, what is the point of this complication? I will very briefly show in an example where I am using this. Like all architecture setups, it might turn out later to be a horrible idea. But for the initial tests, it seems like a decent set up.

Behaviour System

The goal is to be able to attribute different behaviours to a single object. To achieve this, I created a Blueprint Class called ExampleObject. For this Class I added an array of Class References of type Behaviour as a public variable. Now I can drop this actor in the level and in its properties section assign as many different type of Behaviour as I want. In this example it would be:

At the moment the list, Desired Behaviours holds only a MoveUpBP type in it. But if I had a Pullable or a Grabable Behaviour, I could have also added it to the same list, since they all have the base type Behavior.

As the first example, I will have the Behaviours as actors themselves, I need to spawn them in the level. I do that in the Begin of the ExampleObject:

Like this, I will have all these Behaviours, which I can dynamically add or remove and they can hold per instance data about the ExampleObject, change any of its attribute by receiving an AActor* to it on their methods and be shared between different objects.

You can easily go through the set up above and add other methods. For example I added an Update for these Behaviours:

Of course your methods could also accept arguments, which they should if they wish to modify the ExampleObject.

Lastly you can have ExampleObject derive from a C++ type itself, where you automatize all these initialization and function calling, so that all you truly interact with is a list of Behaviours you can add to any object which derives from this type.

Actor Components

The problem with the method above is that the Actor has way more overhead than what we need. We just need a container that holds C++ and Blueprint logic. Luckly Unreal has a system just for this, it is called the Actor Component. Instead of deriving from Actor, we derive from Actor Component, and just like that we have a place we can write C++ code, as well as Blueprint logic, without having an overhead of having physics, rendering, transforms etc.

Components could get really big if you wanted them to. You could go beyond of them being a simple container to having them contribute to rendering and physics.

While Components can be added to your system in runtime, Epic suggests to avoid that as much as possible because of performance reasons. In my example, I don’t actually need the array anymore, I can simply click on “Add Component” in my ExampleObject Blueprint class and add my behaviour as a Component to my ExampleObject. I could get a reference to this Component by dragging it in my Blueprint and call its Update or Start method.

If all you want to do is Start and Update, with no extra paramaters passed on or the need of a rigid control of when the functions are called, you can also use the Tick and Begin Play events which are also called for the Components (if you have it on per Component). Like this your Component system has bare minimum need of a setup, and is ideal for most use cases.

--

--