What are Local Variables

Unreal Blueprint graphs support Local Variables. They are useful for storing intermediate state of operation to speed up things - like caching component at beginning of the function.

Local Variables in Functions

Local Variables are supported in function. You can define them in the My Blueprint tab and reference them only inside the graph of the specific function they are created for.

Blueprint editor showing Hello World function with a Set node a local boolean variable called Hello which sets it to false.

Blueprint editor showing Hello World function with a Set node a local boolean variable called Hello which sets it to false.

Local Variables in Macros

Unreal Macros have the ability to define internal local variables. They are used to implement anything that requires state. Unreal implements them as Local nodes that are placed in Utilities → Macro category of the palette.

The lifetime of the local variable defined in macro depends on where the macro is executed from.

Example macro function with Local Integer variable and open palette showing few of the available types.

Example macro function with Local Integer variable and open palette showing few of the available types.

Example - DoOnce node that needs a boolean variable to make sure the code flow won’t pass it singal twice.

image.png

Local Variables in Event Graph

There is no support for creating own local variables in event graphs. The only local variables that exist in context of the Event Graph are the ones from the macros.

Pitfalls

In functions

Implementation wise, locals in functions are stored in the stack frame of function execution. So same limitations apply as in any system that uses stack frames. When you do deep recursion you may in the end run out of stack space which can cause a problem.

This also means all flow control nodes are limited to this specific execution. Here is an example of graph that works a bit different than expected.

image.png

When you use DoOnce node this way, you might expect the call to HelloWorld from outside will call it twice. This is not the case. This code results in infinite loop. What is happening is this DoOnce is unique to each execution. This is because the local variable that is created by the DoOnce node is limited to the execution of the function - so another execution has new instance of that variable.

In Event Graph (Ubergraph)

Blueprint Event Graph (In code called Ubergraph) has also concept of local variables, however their lifetime is much different.

To solve any asynchronous nodes the stack is not local to execution of an event or function - instead it is shared to whole execution of ubergraph - it has pretty much the same lifetime as any member variable of the blueprint.

This can be observed if you try implementing a recursive function that runs a for loop, which is based on integer local variable.

Example of recursive Blueprint Event that runs a loop 4 times prints string and prints string from inside of it.

Example of recursive Blueprint Event that runs a loop 4 times prints string and prints string from inside of it.

Output of this event is:

Hello
Hello
Hello
Hello
Hello

This is not something one may expect. As in this example you would expect 4 x Hello from the top-level call and another 4 x Hello from each of the 4 deeper level calls - which in that case should be 4 + 4 * 4 = 20, yet we have 5 lines.

Why? Let’s check how For Loop is implemented:

image.png

This is because the local variable is tied to the whole graph, so each execution has it shared. It causes it so we will only get full 4 iterations from the deepest recursion level. The top-most will just do single iteration.

More things to check for curious engineers

Kudos

Kudos to colleague at work (Need to ask if i can share a name 😀) who found few mistakes in my reasoning about recursion pitfall.