[UE5][Intermediate] Integrating CommonUI and Enhanced Input into Gameplay
What problem does it solve?
Common UI is a very promising technology for coping with biggest issues of UMG. It's beta state makes it prone to changes that aren't reflected in documentation and tutorials aren't up to date. This article shows how to set it up for UE 5.5 in a real gameplay scenario, where focus needs to seemlessly switch to UI for both Mouse + Keyboard and Gamepad.
Background
During my 10+ year career as Unreal Engine Programmer I developed UI for several projects and there was always an issue with Gamepad support in:
- Moving focus between widgets
- Integrating Gamepad driven Gameplay with UI
- Seemless switching between Mouse + Keyboard and Gamepad while maintaining focus
Those issues, along with many others like global styling, were to be solved in CommonUI plugin. It took over a week to make it work as intended and this article aims to save you the time.
Prerequisities
For simplification I assume you already have Unreal Engine 5.5 installed and know how to handle basic operations.
Additionally you need some background about how Common UI and Enhanced Input work. This article focuses solely on integrating them.
Research
Magnificent article on CommonUI setup
Epic's Official documentation - misses newest changes - especially that CommonUIActivatableWidget Activates itself on moving back on Stack. Manual Activation breaks the system!
Epic's Official YouTube Tutorial - massively outdated and only shows Main Menu, without Gameplay.
YouTube Tutorial #1 - doesn't include Gameplay under UI.
YouTube Tutorial #2 - uses SetInputMode nodes which breaks CommonUI.
Result
Final result of Common UI and Enhanced Input integration in Gameplay Context
Downloadable project
Solution
TL;DR version
Main findings are:
- PushWidget Activates CommonActivatableWidget now, so you shouldn't call ActivateWidget yourself.
- SetInputMode is illegal to use with CommonUI and breaks it. You should use GetDesiredInputConfig instead.
- To properly handle the InputConfigs in Stack make sure that there's a default RootContentWidgetClass that handles setting it to Gameplay configuration.
Regular Version
Create project from Third Person template
Blueprint/C++ version doesn't matter

Add Clickable Gameplay
The most troublesome aspect is to have a clickable environment as part of the Gameplay, the one that was recently served by SetUserInputGameAndUI.
First let's crate an InputAction IA_GoTo and add it to Input Mapping IMC_Default with Left Mouse Button binding.


Next, create a PlayerController Blueprint called BP_TutPlayerController and configure it in Selected GameMode settings in World Settings.

Now open the created Player Controller and create method GetLocationUnderCursor. Configure it according to the image below.

In the Event Graph add IA_GoTo event and call SimpleMoveToLocation on data from GetLocationUnderCursor.

Finally we need to show the hidden Mouse Cursor in Class Defaults.

To make it work we lack NavMesh so let's add it NavMeshBoundsVolume from Place Actors Window and scale it up to contain whole level.

Now you should be able to click on the level when playing to move to desired spot.
Create HUD Class
For managing Widget's HUD class is handy, so we create BP_TutHUD and configure it in the WorldSettings.

Enable CommonUI plugin
Go to Plugins Window and Enable CommonUI Plugin (beta).

Restart project afterwards.
Set Game Viewport Client Class
Open Project Settings, find GameViewportClientClass and set it to CommonGameViewportClass.

Don't restart project yet.
Enable Enhanced Input Support
Find EnableEnhancedInputSupport and Enable it.

Now you can restart the Editor.
Obtain input keys images
We need key images to be shown in UI ActionBars. I'm using Xelu's FREE Controller Prompts with a Creative Commons license. Drag and drop them into the project afterwards.
Create CommonUI configuration files
We need several assets to configure the CommonUI
- TutCommonInputActionDataBase of class CommonUIInputActionDataTable
- TutCommonInputBaseControllerData_GP of class CommonInputBaseControllerData
- TutCommonInputBaseControllerData_MKB of class CommonInputBaseControllerData
- TutCommonInputData of class CommonUIInputData

TutCommonInputActionDataBase contains info about all the inputs being used in CommonUI. Basic settings limit to providing keys and images of those keys. We need NavigateBack, NavigateForward, TabLeft and TabRight.

TutCommonInputBaseControllerData_GP (Gamepad) and TutCommonInputBaseControllerData_MKB (Mouse and Keyboard) contain details on how inputs look and behave per input device.
Configure them accordingly:


TutCommonInputData requires EnhancedInput InputActions.
Create IA_UI_GenericAccept and IA_UI_GenericBack and configure them in IMC_Default:

Now configure the TutCommonInputData accordingly:

Fill in CommonUI Project Settings
Having all the pieces we can configure the CommonUI Project Settings.
First set the InputData to TutCommonInputData.

Next scroll down to Platform Input Windows and apply the settings:

Create Styles
Although not mandatory, it's nice to have a CommonUI project styled from the beginning. CommonUI introduced a well known from other front end enviroments global styles, so you can create a button style that is automatically applied to each CommonUIButton!
Create 3 different Styles:
- CommonStyleBorderBase of type CommonBorderStyle
- CommonStyleButtonBase of type CommonButtonStyle
- CommonStyleTextBase of type CommonTextStyle
and configure them in Project Settings:

UI architecure
Finally we can create the CommonUI Widgets. Basically, many of the regular UMG widget classes got their twin in CommonUI and those are now mandatory to be used.
The idea is to have a base WBP_HUD widget container which opens a WBP_IngameMenu. That widget has 3 buttons - Resume, Settings and Quit. Settings button opens a WBP_Settings widget which allows Tab switching. Tabs wll become consecutively: Video, Audio and Gameplay.

Creating widgets
Buttons
First we need a basic button. Let's create a WBP_ButtonBase of class CommonButtonBase.
Now create children of that WBP_ButtonBase: WBP_MenuButton and WBP_TabButton.
Finally we need an WBP_ActionBarButton of type CommonBoundActionButton.
WBP_ButtonBase will serve as a template for more specified buttons. It requires a CommonText and a CommonActionWidget placed in an Overlay.

If everything is set up properly the Bind Widgets Window should show a green check mark.

You can now set a DesignTimeKey setting to check if TutCommonInputData is properly bound.

in the EventGraph we expose the variable Text and apply the text on certain events to the ButtonText.

WBP_MenuButton is going to be used just as a higher level of abstraction of ButtonBase (you should never use Base classes directly as they suggest being abstract).
WBP_TabButton will be used for WBP_Settings widget and we don't want to have the InputActionWidget visible so we hide it:

WBP_ActionBarButton is a different story and will be used in ActionBar of the WBP_IngameMenu which shows all available inputs and their actions.
We configure it similarly to WBP_ButtonBase but now CommonText needs to be named Text_ActionName.

I used ScaleBox as well to better fit the widgets inside ActionBar container.
In the Bind Widgets tab there should be 2 bindings approved.

Menus
HUD
As described in the UI Architecture section we first create a global conainer WBP_HUD. It needs to be of type CommonUserWidget.
WBP_HUD is a host for a Stack of widgets that will contain our menus.
Add a CommonActivatableWidgetStack and call it MenuStack.
That's why we should create a WBP_StackStub of class CommonActivatableWidget and set it to RootContentWidgetClass.

Now in WBP_StackStub we need to overwrite GetDesiredInputConfig

Additionally a CommonBoundActionBar can be handy to display available action keys.
Hierarchy should look like this:

Now go to BP_TutHUD and make it show up on BeginPlay.

Ingame Menu
Let's create WBP_IngameMenu and WBP_Settings of type CommonActivatableWidget.
For WBP_IngameMenu we need 3 WBP_MenuButtons to handle our Resume, Settings and Quit features.
Most importantly you need to set the IsBackHandler and IsBackHandlerDisplayedInActionBar to true.

In the EventGraph we set the OnClicked events of the Buttons.
Additionally, we need to tell the system which Button is our default one by setting the Focus OnActivated.
PushWidget is a method for managing Stack on WBP_HUDs MenuStack. Let's add a configuration variable ParentMenuStack for pushing new widget.
Until around version UE 5.5 Pushed Widgets required calling ActivateWidget, which made the widget to show up and handle inputs. After a lengthy debugging session I found that those PushWidget effectively Activates widget as well (even wighout AutoActivation setting). Calling it twice can break the initialization logic!

2 methods are required to be overridden.
GetDesiredFocusTarget should return the ReturnButton.

GetDesiredInputConfig serves as a replacement to former SetInputMode (which is illegal to use with CommonUI).

First test run
To finally test if we made CommonUI to work we need to handle EnhancedInput InputAction.
Create IA_OpenMenu, add it to IMC_Default and configure Gamepad's StartButton and Escape on keyboard.

Using Escape in Editor is troublesome as it closes the PIE (Play In Editor) session. You can either remove the Escape binding from Editor Preferences or add a Chorded Action Trigger to use key combination. If so, create IA_ShiftChord, add it to IMC_Default and set it to Shift. Now add another key binding to IA_OpenMenu with Escape but now add Trigger Chorded Action and configure it to use IA_ShiftChord.

Now we need a set of OpenIngameMenu calls. Let's start with WBP_HUD.

We added a branch to check if the stack is empty or set to default so we don't open menu again (it causes creation of new widget).
There's also a configuration just after pushing the widget so we can callback the MenuStack.
Next step is routing the code by BP_TutHUD.

Finally we can serve the IA_OpenMenu in BP_TutPlayerController.

Now run the game and press any key you've bound the IA_OpenMenu to.

Adding WBP_Settings
To prove that widget stacking works we will now configure the WBP_Settings.
We need few additional widgets first:
- WBP_TabWidget of type CommonActivatableWidget
- WBP_TabListWidget of type CommonTabListWidgetBase
The WBP_TabWidget is where we can populate settings for the game. For our purposes it will only contain a CommonText with it's name.

And corresponding EventGraph with exposed TabText variable.

WBP_TabListWidget is for controlling which TabWidget is going to be viewed.
In the hierarchy we add a HorizontalBox named ButtonsContainer and we can fill it with some test Buttons to see how will they look when added dynamically.

The default settings need to be altered for listening to proper InputActions

In the EventGraph we need to implement 2 methods - HandleTabCreation and HandleTabRemoval. Additionally we clean any Button tests from the widget on Construction.

In the WBP_Settings first we enable the Back Handlers.

The Hierarchy contains CommonActivatableWidgetSwitcher with 3 WBP_TabWidgets.
On top there's a HorizontalBox with 2 CommonActionWidgets for displaying keys and WBP_TabListWidget for WBP_TabWidget selection.
CommonActionWidgets need to have InputActions configured accordingly.

The EventGraph configuration is a little complicated.
We need to link WBP_TabListWidget with CommonActivatableWidgetSwitcher, register Tabs with WBP_TabWidgets and configure TabButtons.
Lastly we stretch the Buttons in ButtonsContainer as they were added dynamically.

We also have a single utility method for configuring the WBP_TabButtons.

Now we can Play the Game again and check if Settings are properly traversed.

This consluded the tutorial!
Conclusions
CommonUI is promising though difficult to configure plugin. Hopefully it will be more straightforward to configure when it leaves the Beta stage.
Possible improvements
There're a lot of other UI widgets to create that can cause trouble
- Clickable widgets on HUD
- Dialog boxes
- Complicated drag and drop widgets like Inventory