30 Sep 2023

How to create a console menu using CommonUI

Michu San
By Michu San Unreal Engine Developer

In the following post, I will show you how to use UE5’s CommonUI plugin to build a User Interface. We will create a simple Pause Menu with settings that work on PC and console.

CommonUI provides navigation within the active widget and prevents leaving an active widget to another in the background. Also, it allows us to get stacks of widgets and move between them. It also gives the opportunity to create styles for buttons, texts, borders, and text scrolls. It is recommended to use it from the beginning of the project if it’s going to be released on modern consoles as it simplifies many aspects of the UI for consoles.

Setting up CommonUI is quite complex so don’t hesitate to check out our demo project:
https://github.com/TheSamurais/CommonUIProject

Plugin setup

First, we need to activate the CommonUI plugin in the editor:

Pic 1 – Activating CommonUI plugin.

After that, we need to find the viewport class in Edit -> Project Settings -> Engine -> General Settings -> Game Viewport Client Class, set it to CommonGameViewportClient, and reset the Editor:

Pic 2 – Setting viewport general class.

Input binding setup

This high-level dependency diagram of the Common Input Settings shows how bindings are connected:

Pic 3 – Common Input Settings dependency diagram.

In Edit -> Project Settings -> Game -> Common Input Settings -> Input Data we create a blueprint of type CommonUIInputData with the name CommonUIInputData. Later we will go back here to set input settings for confirm and back actions in this blueprint:

Pic 4 – Creating CommonUIInputData blueprint type.

For this blueprint, we need sets of inputs to use in our widgets so we need to create a CommonUIInputActionDataTable:

Pic 5 – Creating CommonUIInputActionDataTable.

Inside this data table we will set up buttons: confirm, back, tab left, and tab right:

Pic 6 – Populating CommonUIInputActionDataTable.

The “Confirm” action on the PC cannot be overridden in CommonUIInputActionDataTable and it is hardcoded to “Space” (tested in UE 5.2).

Now we can go back and set input settings for “Confirm” and “Back” actions in our previous blueprint CommonUIInputData:

Pic 7 – Setting up confirm and back actions in CommonUIInputData.

Now, to bind these input actions to the proper UI glyphs we need to add a ControllerData (Pic 8.), i.e. one for Mouse and Keyboard and another for XBox Gamepad. Then, we go back to Edit -> Project Settings -> Game -> Common Input Settings -> Platform Input and here we connect the ControllerData to our platforms (Pic 9).

Pic 8 – Creating ControllerData.
Pic 9 – Setting ControllerData per platform (Windows here).

Remember to change the DefaultGamepadName to the same name that is used by ControllerData – by default it should be changed from “Windows” to “Generic”. If you compiled your Engine with consoles SDKs, you can choose different GamepadName in the ControllerData.

Then, inside the ControllerData, we bind gamepad buttons to their respective glyphs:

Pic 10 – Example InputBrushDataMap in ControllerData for Xbox controller. Icons downloaded from https://thoseawesomeguys.com/prompts/

Creating UI

Before we begin forming our UI we need a couple of things:

  1. WBP_MenuButton of type CommonButtonBase
  2. WBP_TabButton of type CommonButtonBase
  3. WBP_ActionBarButton of type CommonBoundActionButton.

CommonUI allows us to change the style of any button (selected, hovered, pressed) through the CommonButtonStyle class. We can set the style in one place and then attach it to any descendant of CommonBaseButton. So for example we can create a style for menu buttons and another for settings buttons:

Pic 11 – Blueprint of the CommonButtonStyle class.

WBP_TabButton selection with gamepad/keyboard will use the “selected base” style by default (white color).

Styles can be chosen per button or we can assign CommonButtonStyle style to buttons. The latter will change all buttons that have this style attached.

In WBP_MenuButton beside the usual text, we need to add a CommonActionWidget and name it exactly “InputActionWidget” so it is bound for visualization behavior:

Pic 12 – Hierarchy of the WBP_MenuButton.

Inside the WBP_MenuButton graph, we add a new variable ButtonText that is Instance Editable and set it to the ButtonTextBlock:

Pic 13 – Setting button’s text.

Similarly, we create WBP_TabButton. The only change here is we can choose different style for this button. Also, we don’t need to add InputActionWidget as its input icon will not be used here.

Pic 14 – Hierarchy of the WBP_TabButton.

Next, in WBP_ActionBarButton we need a CommonText and InputActionWidget. Same as in WBP_MenuButton, components need to have specific names, otherwise they won’t work automatically with ActionBar. The CommonText needs to have the name “Text_ActionName” as in the menu Window -> BindWidgets (Pic. 16). You can see the checkmark next to the Property, so you know the widget is bound correctly.

Pic 15 – Hierarchy of the WBP_ActionBarButton.
Pic 16 – Bind Widgets tab.

TextBlock named “Text_ActionName” is mandatory and the widget blueprint will not compile if it is missing.

When our inputs and button classes for UI are ready, we need to set up a base for our UI – a container widget. Let’s call it WBP_MainContainer and it would be of type CommonUserWidget. In there, we add CommonActivatableWidgetStack and CommonBoundActionBar:

Pic 17 – WBP_MainContainer hierarchy.

We will keep our widgets on a stack and show current action bindings on ActionBar. Now we need to add the widget into the view. Inside BoundActionBar we need to specify which button class we want to use for our control bar. I our case it’s WBP_ActionBarButton:

Pic 18 – Action Button Class for BoundActionBar widget.

After that, we want to display this container on screen. For proper setup, we will add it in the player character with EnchancedInputAction IA_PauseMenu which supports keyboard and gamepad:

Pic 19 – Pause Menu under the IA_PauseMenu in the player character.

Now, we need to create our WBP_PauseMenu of type CommonActivatableWidget class. It will contain 3 buttons of class WBP_MenuButton: continue, settings, and quit game:

Pic 20 – Hierarchy of the WBP_PauseMenu.

To show the WBP_PauseMenu we push it to the WBP_MainContainer. Also, we need to activate the widget if it is not set to auto-activate:

Pic 21 – Pushing Pause Menu.

We also want to use back binding to close the menu. We need to go to the WBP_PauseMenu and set the Class Defaults as follows:

Pic 22 – Pause Menu details settings for back handler support.

With that, we need to override OnHandleBackAction to properly handle exiting the pause menu and regain focus on the game:

Pic 23 – Overriding OnHandleBackAction function.

To gain focus on the activation, a GetDesiredFocustTarget() function needs to be overridden and return the button that we want to focus on:

Pic 24 – Supporting initial keyboard/gamepad focus.

Now, let’s prepare a settings menu with few tabs. For adding tabs to UI, we create WBP_TabListWidget of the CommonTabListWidgetBase class. Inside, we add a horizontal box and bind two events: “Handle Tab Creation” and “Handle Tab Removal”. This allows us to add and remove CommonButtons in the UI.

Pic 25 – Hierarchy of the WBP_TabListWidget.
Pic 26 – WBP_TabListWidget events.

The important thing is to set “Next Tab Input Action Data” and “Previous Tab Input Action Data” in details of the WBP_TabListWidget. This way we will be able to navigate the tab list using bindings.

Pic 27 – WBP_TabListWidget bindings.

The next step would be to create a settings widget WBP_Settings of type CommonActivatableWidget. It contains:

  1. CommonActivatableWidgetSwitcher with 3 example WBP_TabWidgets of type CommonActivatableWidget
  2. 2x CommonActionWidgets displaying glyphs for tabs navigation
  3. WBP_TabListWidget containing buttons for jumping between tabs:
Pic 28 – Hierarchy of the WBP_Settings.

In the details of the WBP_Settings, we set the same settings as in WBP_PauseMenu to provide the “go-back” support.

Now we link the tab widget with the widget switcher and register tabs to populate our tab list widget:

Pic 29 – Linking tab list widget with switcher and registering tabs.

Then, to change the text on buttons we create a custom function and we set their texts based on TabNameId.

Pic 30 – Function for setting button’s text.
Pic 31 – Setting every button’s text.

Finally, we need to bind CommonInputActionWidgets with their respective actions:

Pic 32 – Binding ActionWidget’s Input Actions.

Now, the last thing we need to do is to implement the Settings Menu opening from the WBP_PauseMenu(Pic.33).

Pic 33 – Pushing Settings menu from Pause Menu.

The final effect should look like this (tested on Xbox Series X):

Pic 34 – Preview of simple CommonUI menu.
Michu San
By Michu San Unreal Engine Developer
SIRBart

Call The Knights!

    Table of contents