Unreal Pure Functions — Your tricky friend
This article is aiming to help Unreal Blueprint learners (especially who don’t come from a professional coding background) to better understand pure functions and avoid making mistake around it.
What Unreal’s documentation tells you and doesn’t tell you
In a Blueprint, you can check the Pure checkbox of a function to make the function pure:
Pure functions don’t have executive pins, and it will be automatically executed when their output data is required:
However, I found part of Unreal’s documentation about pure function a bit confusing. It says:
Pure Functions promise not to modify state or the members of the class…
But what does “promise” mean?! It “can” or “cannot”?!
Well, you can easily do a test, and you will find out that Unreal is that kind of person who doesn’t take promise seriously… Pure functions can modify state or members of the class.
You can do things like this:
There is no error when I compile this pure function, and it changes the colour of the UI widget and the variable successfully.
Okay, so when it says promise, it means you can but ideally you shouldn’t, because pure functions should only be used as a data provider rather than data changer, as Unreal’s documentation says,
Pure Functions are generally used for getter Functions or operators that just output a data value.
But what if you want to keep that promise seriously? You can make the function not only pure but also Const. Once you select the Const, you can’t change things now, and it will give you errors on the Set nodes.
So, if pure functions can change things (if you just ignore that promise), what is the actual difference between pure and impure functions in Unreal? I think eventually it’s mostly about how they are being called. Now say it loudly, “pure functions are automatically executed by the compiler EVERYTIME the data relying on them is required”. If you forget this, you might make same mistakes as me which we are going to talk about below.
Don’t be fooled by pure functions!
(Now I’m going to share some mistakes I made around pure functions :D)
A very straightforward example is like this,
Apparently, you will get two different random integers printed, because the pure function Random Integer is called twice. This case is very obvious but it can get a bit more deceptive.
Here is an example of the mistake I made before. You can be fooled by a pure function if the pure function has multiple outputs and you try to cache them. To demonstrate this, I made a pure function that returns a two-digit integer and its ones and tens.
If I cache the outputs like these…
The pure function is called three times in this case, so the two-digit number and the ones and tens we saved are from three different random two-digit integers, and the printed result will be like,
Two Digits:75 Ten:5 One:8
Yet, if we only run print once like this, then the Randomize pure function is only called once:
The result will then be correct:
Two Digits:72 Ten:7 One:2
If you want to cache the multiple outputs from a function, it’s better to make it an impure function, because impure function caches the outputs.
So, if we change that pure function to impure:
we will get consistent result now,
Two Digits:93 Ten:9 One:3
because Randomize_Impure only runs once and the three outputs are cashed by it.
This is basically it. But before I wrap up, here is a bonus example:
Function Random will only run once here, and give the three FunctionPure2 same output data. If you want the FunctionPure2 to have different input data you need to do this:
The Take Away
As I’ve been fooled by pure functions a couple of times, now whenever I hook the output pin of a pure function to more than one execution nodes, I’ll think twice or even duplicate the pure function rather than hooking up the output pins to multiple execution nodes.
Reference & recommended reading/watching:
https://www.gamedev.tv/courses/635498/lectures/12052714 (highly recommend, very good tutorial and it’s free)