Stateless UI with UMG through blueprints

I come from a React.JS world where stateless UI is currently a great way to manage things. Let me try to apply same approach with Unreal Engine 4 and its UMG along with an event dispatchers and an interface.

The most important part of a stateless solution is about keeping all UI widgets from keeping state of the game on its own. Those are merely a for displaying and potentially changing such state. Usually having an object that acts as an authoritative source of truth and dispatches changes to interested parties is much better way.

Let’s go with an example right away. I want to display set of buttons representing player’s tools. Player can use only one tool at a time so these buttons needs to reflect such fact. Player should be able to either click on a button or press keyboard shortcut and tool can be changed by some other means.

A tool switching logic should be created first without even making any attempt at UI as it allows to think separately of it. There are numerous ways to achieve that. I would go about creating a new interface first.

Simple interface used to mark any class as a tool

This approach gives a great power as I don’t need to block inheritance chain just for this. I can create an Actor derived class or something that’s actually worth inheriting, eg. Pawn. All of them can carry tool information without interfering with inheritance. And besides that it can implement actual logic and in game appearance for such tool.

Implementing interface within an Actor class

For a simplicity I am using a tool name as a string, but it can be any sort of identifier to eg. find correct row in a related datatable to read values for such tool.

Make a variable with currently selected tool

Next step is to make an actual logic for changing the tool. It can be done it in some new actor that would handle just that or any of global-ish objects (eg. Player Character, Player Controller) will do too. Note that I am making this private variable as I consider it a good practice to avoid uncontrolled changes to it.

In a same class right under list of variables create a new Event Dispatcher. I am going to call it Current tool changed. In details panel add an input with ITool type which will carry information about new tool. To actually change a tool, create a new public function and simply wire it like this.

Single point where tool can be actually changed.

Whenever something needs to change a tool, this function needs to be called and it will automatically inform other objects when that happens and what a new tool is.