Delegates in C++ are used in a number of cases. However, in this post, think of delegates as pointers that point to specific functions. Having said that, through delegates we can call the functions that they are pointing to when something happens. In fact, you might already seen delegates in UE4 in a number of cases.
For example, in a previous post in order to generate overlap events through C++ we used the following lines of code:
One could say that OnActorBeginOverlap and OnActorEndOverlap are delegates. When your actor begins to overlap with another actor, the delegate OnActorBeginOverlap will check if it’s pointing to any valid functions. If so, it will fire all the functions which are bound to it.
Understanding “valid functions” and “bound”
Before we jump in to create our own delegates let’s explain what “valid functions” and “bound” means. Each delegate accepts functions with a certain signature. A signature of a function constitutes of two things:
- The return type (ie void, int32, float)
- The parameters list
For example the following functions, all have different signatures:
- void MyFunction() (in this case the return type is void and the function has no parameters)
- int32 FunctionWithReturnType() (in this case the return type is int32 and the function has no parameters)
- void DoSomething(float x,int32 y) (in this case the return type is void and the function has two parameters, a float and an int32)
Note that the types that are included in the parameters list matter. For example the following functions have different signatures:
- void DoSomething(float x, int32 y)
- void DoSomethingElse(int32 x, float y)
In this post, we will see two types of delegates:
- Delegates that accept only one function (single-cast delegates)
- Delegates tha accept more than one functions (multi-cast delegates)
The bound functions in each delegate are the functions that are hooked up to it. This means that if a delegate has three bound functions to it, when we call it, it will fire all the functions in the reverse order we added them. (Later in this tutorial, we will see how we can bind and call functions from a delegate). Let’s say that we added the following three functions to a delegate:
- void MyFunction()
- void MySecondFunction()
- void MyThirdFunction()
If we tell the delegate to fire the functions that are bound to it, the expected order is:
Having explained that, we’re ready to create our own delegates. Let’s start!
To declare a delegate in UE4 we use a corresponding macro for our needs. Use the following table (taken from the official UE4 documentation page) to find the declaration macro to use to declare your delegate:
So, having said that, let’s start!
- Create a C++ class based on the Actor class
- Create a BP based on your C++ class
- Place the BP in your level (in order to test for outputs later)
In your header file, right after the GENERATED_BODY() macro type in the following code:
Make sure you mark your functions with the UFUNCTION macro. Otherwise your game will crash when you will try to call them through delegates.
Switch to your source file and add the following implementations:
Now that we have the declarations and implementations of all the functions, go inside the BeginPlay function and right after the Super::BeginPlay() add the following code:
Note the lines 18 and 29. We execute the bound functions with a value we decide in that particular moment. I decided to call the IntDelegate with a value of 50 and the Del with a value of 10. These numbers just poped into my head. Feel free to expand this code as you wish!
If you compile and run your code with the same assigned values, you will get the following result in your log:
A very important thing to mind is to make sure that your delegates have bound functions before you try to call them. To check that, all delegates have the following function:
- IsBound() which returns true if there is any function bound to your delegate
Moreover, keep in mind that:
- To call single-cast delegates use the Execute(<optional parameters go here>) function
- To call multi-cast delegates use the Broadcast(<optional parameters go here>) function
For more information about delegates make sure to check the official UE4 documentation page.