I’ve got a suitable basic framework using CommonUI setup in UE 4.27.
Most everything is working as expected except that I cannot get the universal back key to ever register. I have tried everything shown in all the examples I have found to no avail. However, I a workaround is not difficult. I’ll show that workaround here:
First, I will not detail all of the basic prerequisites for setup already covered in documentation and the links in the first post. I’ll just overview basic setup here and discuss the caveats.
Basic prereq data:
Core elements of this system:
Component is responsible for Pushing widgets onto stack, reverting to game mode when the stack is cleared, and creating the initial base stack widget.
Caveats of note are that the base stack widget needs to be Activated and Deactivated appropriately, otherwise your mouse will appear while in game only input mode.
Why am I checking for a clear stack on Tick? Because otherwise you need a short delay if firing it from an event, and sometimes if you press keys rapidly you can pop the widgets but still remain in UI only mode, which locks the game. Checking on tick neutralizes this problem as far as I can tell.
Menu Stack widget?
Stack widget is just empty widget except the stack. You could use multiple stacks in there if you need.
And the final piece of the puzzle:
A common parent class that all menus will be derived from. It holds events for forward and backward travel, but you can add anything extra you want.
The main reason for this common parent is because I cannot get the in-built back handler functionality to work. This is the workaround. But it gives you flexibility for many situations so even if back handler was working as expected, you might still use this setup.
Parent Activatable Menu event graph:
Override OnKeyDown to read inputs:
Note - you might think that you could send input via an interface from the controller. You can, except it wont register if you are in UI input only mode. You could use game/UI but then you have to handle blocking input to the character. That can be done, you just have to consider your games structure.
Reading for input in the widget here does a good job of separating the widget from controller so I prefer that.
Notice that I have made a bool for handling the Go Back case.
An example child of this parent:
Thats the whole setup. Benefits are these:
-
Easy communications between complex widget structure. Just send any data to the component for temporary holding, and each widget can query there as needed. Never a need to contact a container, filter through arrays to identify some widget, etc. Comms are just stupid easy.
-
For the flexibility you get, extremely easy setup. It took three days to figure out the weird little caveats because there is almost no documentation, but now it is working fine and dramatically easier to work with than any other UI setup I’ve seen so far.
I’ve intentionally left this framework to be bare bones so that I can easily migrate to new projects and then tailor it as needed without extra bloat.
Well, it was frustrating to get started with but overall Epic has delivered another massive time saving tool here. I can’t overstate how much easier this is making my life - generally working with communications between UI elements is sooooo slow and tedious. Now its a breeze.
One thing I’d like to see is a few more exposed events to bind to from the stack, such as:
OnStackCleared
OnWidgetRemovedFromStack
OnWidgetAddedToStack
stuff like that would just make it easier to keep some clean communications such that individual menus don’t have to handle cases that are better left to a central manager.