While our game may be running without any issues in the editor or even in…
Utilizing Unreal Engine’s reflection system
In this post, we’re going to utilize the built-in reflection system in UE4 to perform changes in our game at runtime. Reflection is the ability of a program to inspect its own code (or other associated code) and change at runtime (for more information about reflection, click here). By default, C++ isn’t capable of that, however Unreal Engine is kind enough and created this ability for us!
In this post, we’re going to create one BlueprintCallable function which will take a single FString parameter. That function will search all the available functions of our object and if it manages to find a function whose name is the same of our parameter, it will execute it. This is the most common case of using reflection.
In case you find yourself writing C++ out of the engine and want to use this feature, a simple workaround is to create a map container with string keys and pointers to functions as mapped types. Then, you can manual search your map and execute your associated function using the corresponding function pointer.
Let’s move on and use the reflection system of the engine!
Utilizing UE’s reflection system
I’ve created a Third Person C++ template project and inside my character’s header file, I’ve added to following declarations:
1 2 3 4 5 6 7 8 |
public: /*This function will search which function to execute*/ UFUNCTION(BlueprintCallable, Category = Reflection) void ExecuteFunction(FString FunctionToExecute); UFUNCTION() void DoSomething(); |
Then, I’ve implemented the following logic:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
void AReflectionCharacter::ExecuteFunction(FString FunctionToExecute) { //FindFunction will return a pointer to a UFunction based on a //given FName. We use an asterisk before our FString in order to //convert the FString variable to FName UFunction* Function = FindFunction(*FunctionToExecute); //When you're using a pointer - make sure to check if it's valid first! if (Function) { //The following pointer is a void pointer, //this means that it can point to anything - from raw memory to all the known types - void* locals = nullptr; //In order to execute our function we need to reserve a chunk of memory in //the execution stack for it. FFrame* frame = new FFrame(this, Function, locals); //Unfortunately the source code of the engine doesn't explain what the locals //pointer is used for. //After some trial and error I ended up on this code which actually works without any problem. //Actual call of our UFunction CallFunction(*frame, locals, Function); //delete our pointer to avoid memory leaks! delete frame; } } |
Compile and save your code. When you’re done with that, add the following Blueprint code to your character:
Here is my output after pressing E a couple of times:
A big thank you to Eduard Gelbling and Sergiu Crăiţoiu for their suggestions and ideas which led to an updated code in this post! You’re awesome!
This article is really cool, but how to pass a variable to the function please?
Hello, in other programming languages which support reflection by default you pass an array of objects and then your program tries to execute the given function by correlating the functions’ arguments with that array. Currently in UE4 I’m unable to find a built-in way to do so.
-Orfeas
Hi, it seems simple to use
Target->ProcessEvent(Fn, Args);
? Is it wrong?snippet from engine
static void Call(UObject* Target, const TCHAR* FunctionName, void* Args = nullptr)
{
if (!Target)
{
return;
}
UFunction* Fn = Target->FindFunction(FunctionName);
if (Fn)
{
Target->ProcessEvent(Fn, Args);
}
}
Hello,
Even if I haven’t verified that this snippet works, it’s not unusual that the engine may provide multiple way to utizile a functionality. It depends on your use case and your needs.
Having said that, I wouldn’t say that your snippet is wrong.
-Orfeas
hi.
thanks for this incredibly helpful article.
I am curious to know is there any way to get the return value of a function?
Hello,
That’s actually a good question, unfortunately I haven’t investigated this at the time of writing this comment.
You should probably check the engine’s code.
-Orfeas
Hi. This post was very helpful to me.
And I have a question.
With the Unreal’s reflection system, can I expose, use or search any properties on an UObject too?
Sorry, but this solution simply crashes engine. Tested in 4.26