Epic Games: Introduction to Common UI
Published 2022-07-22 by Epic Games Inside Unreal, guest Mike Prinke, Technical Writer @ Epic Games
This is basically a brain dump video. Mike shows us:
- How to create a new UE 5 project and implement
CommonUI
- Configure Input
- Configure Project Settings
- How to configure Common UI Styles
- Create
UI_Base
widget- Add to Viewport via custom
PlayerController
- Add to Viewport via custom
- Create
UI_MainMenu
widget- Push onto
UI_Base
.Menus
stack
- Push onto
- Create
UI_GenericPrompt
widget- Push onto
UI_Base
.Prompts
stack - Implement generic Yes/No prompt functionality in Blueprints
- Push onto
- How to manage which Widget gets Input Focus
- Especially important for Gamepad or Keyboard navigation users
- Demonstrates but does not actually complete display of Controller-specific Gamepad icons on buttons
Full Video (2h 41m)
Annotation
Introduction
Setup New UE5 Project
New Data Table: InputActionTable
- 0:20:06 - New Data Table:
InputActionTable
<CommonInputActionDataBase
- Configure Input Actions that UI will respond to
- Can have multiple nested data tables if needed
- Make input action entries:
Confirm
(KB=Enter
, Gamepad=Gamepad_FaceButton_Bottom
)Cancel
(KB=Escape
, Gamepad=Gamepad_FaceButton_Right
)TabLeft
(KB=Q
, Gamepad=Gamepad_LeftShoulder
)TabRight
(KB=E
, Gamepad=Gamepad_RightShoulder
)- 0:23:52 - How to configure Console-specific Button Overrides
- 0:24:38 - Add Gamepad Input Override
- Need source-compiled Engine to be able to configure specific consoles
- 0:24:38 - Add Gamepad Input Override
Create and Configure: ControllerData
- 0:26:09 - Create ControllerData Blueprints
- Initially the names of these are erroneously
InputData...
but they are renamed toControllerData...
@~ 37 min ControllerData_PC_Keyboard
<CommonInputBaseControllerData
ControllerData_PC_Gamepad
<CommonInputBaseControllerData
- Initially the names of these are erroneously
- 0:27:00 -
ControllerData_PC_Gamepad
configuration- 0:27:42 - Configure Input Brush Data Map
- 0:28:10 - Import Gamepad Icons
- 0:28:48 - UI Texture Mass Import Trick
- Select all newly imported texture assets
- Right Click > Asset Actions > Bulk Edit via Property Matrix…
- In Property Matrix dialog:
- Search for “group”
- Change
Texture Group
property toUI
- Select all newly imported texture assets
- 0:28:48 - UI Texture Mass Import Trick
- Configure button textures in
Input Brush Data Map
- 0:28:10 - Import Gamepad Icons
- 0:31:24 - Don’t know what
Input Brush Key Sets
is - 0:31:58 - Controller Texture is an optional texture to represent the controller this config is for
- 0:27:42 - Configure Input Brush Data Map
- 0:32:33 -
ControllerData_PC_Keyboard
configuration
New Blueprint: DemoGameInputData
- Map universal input actions to data table(s)
- Universal Continue input action
- Universal Back/Cancel input action
- 0:37:33 - New Blueprint:
DemoGameInputData
<CommonUIInputData
- Default Click Action =
InputActionTable
.Confirm
- Default Back Action =
InputActionTable
.Cancel
Project Settings
- 0:38:00 - Game / Common Input Settings
- InputData =
DemoGameInputData
- Platform Input
- Windows
- Add Controller Data:
ControllerData_PC_Keyboard
ControllerData_PC_Gamepad
- Add Controller Data:
- Configure other platforms as your game requires
- Windows
- InputData =
Styling Assets
- 0:39:02 - Styling Assets
- New Style Blueprints:
- 0:39:31 -
BorderStyle_DemoGameGenericBorder
<CommonBorderStyle
- 0:39:50 -
ButtonStyle_DemoGameGenericButton
<CommonButtonStyle
- 0:39:59 -
TextStyle_DemoGameGenericMenuText
<CommonTextStyle
- 0:39:31 -
Create Button: UI_GenericButton
- 0:56:01 - New Blueprint
UI_GenericButton
<CommonButtonBase
Configure Button Style: ButtonStyle_DemoGameGenericButton
- 0:57:02 - Configure Button Style
ButtonStyle_DemoGameGenericButton
- Can configure button sounds, textures, colors
- 0:59:44 - Explanation of
Selectable
setting- Used for Radio Buttons & Checkboxes
- For production, consider using textured images rather than tint colors
- 1:01:22 -
Single Material
Setting- Unclear what this setting does
- 1:01:37 - Lyra uses transparent button style
- 1:02:26 - Size Button
- 1:02:44 - Add Common Text Widget
- Verify style =
TextStyle_DemoGameGenericMenuText
- Verify style =
Localization Tangent
Edit Button: UI_GenericButton
- 1:07:39 - Add Text Variable:
ButtonText
- On Pre-Construct: Save default button text value
- Set Button Minimum Width/Height
- 1:09:31 - Review how we created the default button
Create Main Menu: UI_MainMenu
- 1:10:12 - Create Main Menu:
UI_MainMenu
<CommonActivatableWidget
- Add Overlay
- Add Vertical Box
- Add 4x
UI_GenericButton
- Add Spacers …
- Add 4x
- Configure some visual display settings
- Add Vertical Box
- Add Overlay
- 1:13:03 - Configure Buttons
- Set default Button Texts
- Pad buttons
- Name Button Widgets
- 1:14:20 - Wrap Vertical Box with Common Border
- Edit Border Style
BorderStyle_DemoGameGenericBorder
- Edit Border Style
Create Player Controller: FrontEndPlayerController
- 1:16:21 - New Blueprint:
FrontEndPlayerController
<APlayerController
- 1:17:49 - Create new Widget of type
UI_Base
- 1:18:10 - Create & Push New
UI_MainMenu
to theUI_Base
Widget - 1:18:16 -
UI_Base
Review- Suggestion: Base Menu C++ class
- Demonstration in Blueprint
- Note: This is probably better done in C++ with more options & control than BP
- Suggestion: Base Menu C++ class
- 1:19:38 - Add
UI_Base
to Viewport (traditional style) - 1:19:52 - Configure Game to use
FrontEndPlayerController
- 1:19:59 - Create Game Mode:
FrontEndGameMode
- Set Player Controller =
FrontEndPlayerController
- Set Player Controller =
- Game Mode Override =
FrontEndGameMode
- Or however you do this in your project
- 1:19:59 - Create Game Mode:
- 1:20:23 - PIE Verify Main Menu loads
Add UI_MainMenu
Functionality
- 1:21:02 - Add
UI_MainMenu
Functionality - 1:21:08 - Gamepad Focus
OnActivated
:SetFocus
(GetDesiredFocusTarget()
)
GetDesiredFocusTarget()
- 1:22:20 - Override
GetDesiredFocusTarget()
- Discussion of different ways you could compute this value
- 1:24:25 - On Windows, default Input Type = MKB
Project Settings: Engine User Interface
Edit: UI_MainMenu
Create Generic Prompt: UI_GenericPrompt
- 1:31:02 - New Blueprint:
UI_GenericPrompt
<UCommonActivatableWidget
- Visual Layout
- Add Overlay
- Add Vertical Box
- Add Common Border
- Verify Style =
BorderStyle_DemoGameGenericBorder
- Verify Style =
- Add Common Text:
PromptText
- More Steps… Add Yes/No Button
- 1:36:06 - Completed Yes/No Generic Prompt Layout
Implement GetDesiredFocusTarget()
- 1:36:21 - GetDesiredFocusTarget
YesButton
button focussed by default- Rename buttons
YesButton
&NoButton
Implement OnActivated
Event
- 1:36:55 - OnActivated
SetFocus
(GetDesiredFocusTarget()
)
Create Custom Event: SetPromptInfo
- 1:37:27 - New Custom Event:
SetPromptInfo
- Parameters:
- Prompt Text
- Widget that owns this prompt
- Prompt Index
- Parameters:
Edit: UI_MainMenu
Create Custom Event: OnPromptConfirm
- 1:41:55 - Custom Event: On Prompt Confirm
- 1:42:21 - Demo BP is using Integers as “Prompt Index”
- 1:43:40 - Mike does not like this “Prompt Index” solution (suggests using C++ delegates instead)
- Mentions this code he produces is more of “prototype” quality and not fit for a shipping game.
- Good for understanding the flow of events without requiring knowledge of C++.
- 1:44:15 - Spends time trying to see if he can implement delegates with Blueprint
- Not worth watching the “cheat” he spends time trying to find, he ultimately doesn’t find it.
- This tangent goes on for a while, Mike then deletes this work
Edit: UI_GenericPrompt
- Mike implements the “Prompt Index” solution from above
Edit: UI_GenericPrompt
.SetPromptInfo
Custom Event
Implement YesButton
.OnBaseButtonClicked
Event
- 1:47:26 - YesButton Click Implementation
- Mike recommends using Soft Object Pointers
Edit: UI_Base
- 1:49:17 - Add Parameters
- InPromptText - text
- InPromptOwner - soft
UI_MainMenu
object reference - InPromptIndex - int
Edit: PushPrompt
Custom Event
- 1:50:14 - Modify
PushPrompt
Custom Event- Set Event Input:
Activatable Widget Class
=UI_GenericPrompt
- Call
SetPromptInfo()
on the newly added prompt - 1:50:40 - Edit Complete - Visual Reference
- Set Event Input:
Edit: FrontEndPlayerController
New Custom Event: PushPrompt
New Variable: UI_Base
Edit: PushPrompt
Custom Event
Edit: UI_MainMenu
Implement QuitGameButton
.OnButtonBaseClicked
Event
Edit: UI_GenericPrompt
Implement NoButton
.OnButtonBaseClicked
Fix Gamepad Cancel behavior
Edit: UI_MainMenu
- 1:55:35 - Enable
Auto Restore Focus
in Property Details- This doesn’t work, Mike doesn’t know why
- It could be because he didn’t enable the
Is Focusable
property
Edit: UI_Base
Edit: PushPrompt
Custom Event
- 1:56:28 - Bind Event to On Widget Deactivated
- Create Custom Event:
OnClosePrompt
- Create Custom Event:
Edit: OnClosePrompt
Custom Event
- 1:56:53 - Set Focus to Active Widget’s Desired Focus Target
- 1:58:48 - Fix IsValid check on wrong node
- PIE Demo
Another way to do this
Edit: UI_Base
- 2:01:00 - What if? Push Prompts onto
Menu
Stack rather thanPrompt
stack- 2:01:12 - PIE Demonstration
- When opening a prompt, the main menu fades out of view
- Only the top-most widget of a stack is displayed
- Higher priority stacks are displayed on top
- But only one widget is displayed per stack (the highest priority on that stack)
- 2:01:12 - PIE Demonstration
- 2:01:45 - Set Menu Stack Transition Type
- Design Mode: Details: Transition
- Transition Type
- Transition Curve Type
- Transition Duration
- Design Mode: Details: Transition
- 2:02:33 - View Details Panel for
UI_Base
Back Handler Implementation
Edit: UI_GenericPrompt
- 2:02:44 -
Back
.Is Back Handler
Property - Lots of thinking to self about how to solve problem
- 2:06:10 - Enable
Activation
.Is Modal
Property- Discuss
Is Modal
behavior
- Discuss
Edit: UI_Base
Unsuccessful PIE Test
- 2:07:18 - PIE
- This example is still broken, Mike tries to trouble shoot for a while
- He shows his practise project that works the way he wants
Edit: UI_GenericPrompt
Implement: UI_GenericPrompt
.OnHandleBackAction
Method
- 2:09:02 - Implement
UI_GenericPrompt
.OnHandleBackButton
- Exec:
DeactivateWidget
(self
) - Return:
True
- Exec:
Successful PIE Test
Discussion of OnHandleBackAction
- 2:09:30 - Need to explicitly handle
OnHandleBackAction
- Allows for transition systems, etc
- By default, nothing happens on back action, BP has full control
How to Bind Gamepad Buttons to on on-screen Widgets
Edit: UI_MainMenu
- 2:10:37 - Modify
UI_MainMenu
Widget Hierarchy- Add some
Common Action Widget
Common Action Widget
is actually a “Button Icon”- Configure Input Actions for each of these widgets
- 2:13:09 - PIE Test
- Add some
Edit: Project Settings: Common Input Settings
- 2:14:00 - Set
Windows
.Default Gamepad Name
=Generic
- 2:14:38 - Discuss How
Default Gamepad Name
should be configured for each platform - 2:15:23 - Successful PIE Test
There were 2 Editor Crashes @ 2:16:18 & 2:25:00 ish
- Recommend skip ahead to Q&A during editor restart
- or skip ahead to Create Button:
UI_GenericActionButton
- or skip ahead to Create Button:
[NOT SAVED] Edit: UI_MainMenu
[NOT SAVED] Create UI_GenericTabButton
- 2:16:18 - Create
UI_GenericTabButton
<CommonBoundActionButton
- Unreal Editor crash
- This button did not get saved
Q&A While Editor Restart
- 2:17:55 - Q: Does CommonUI work in VR?
- A: Not sure. Answer is probably “Yes, but …”
- Not same type of rendering of UI on screen in VR
- Need 3D world representation of UI
- Add
WidgetComponent
to world Actor, UI would live on that
- Add
- A: Not sure. Answer is probably “Yes, but …”
- Recommend skip ahead to Create Button:
UI_GenericActionButton
- The stuff between now and then is not saved due to another UE Editor Crash
[NOT SAVED] Create Button of wrong type & Delete it
- 2:19:52 - Create Widget:
BoundButtonWidget
<CommonActionWidget
- DELETE Widget
[NOT SAVED] Edit: UI_MainMenu
- 2:20:45 - RB+LB Button Changes
- Add
UI_GenericButton
- Add
- 2:21:59 - Configure
CommonUI
Button classTriggering Input Action
- Would need to add an Action Widget to show the button icon on this button
- 2:23:04 - Implement
Button
.OnBaseButtonClicked
Event- This does not work as Mike hoped
- The changes made in this section do not work, try alternate button type
CommonBoundActionButton
[NOT SAVED] Create Button: UI_BoundActionButton
- 2:25:00 - Create
UI_BoundActionButton
<CommonBoundActionButton
- Unreal Editor crash
[INCOMPLETE] Create Button: UI_GenericActionButton
- 2:26:02 - Create
UI_GenericActionButton
<CommonBoundActionButton
- 3rd time trying to make this button, does not continue
Q&A
- 2:26:24 - Q: How to create Search Bar in UI?
- Seems like Mike misunderstood the question?
- At least, his explanation for how one might go about this is unclear to me
- He seems to be thinking the question relates to searching for widgets of a specific type?
- Recommends adding Gameplay Tags to widgets to facilitate the search
- Some discussion about Gameplay Tags
- Inventory example:
- Search items in inventory for Gameplay Tag
- Display only widgets for items matching that tag