You can use Custom Button widgets in Unreal Motion Graphics (UMG) to create a dynamic, unique menu with animations that the player can interact with. For example, you can animate changes in materials, textures, and text when a player hovers over the Custom Button or clicks it. You can complete the button menu with Verse fields to open and close the User Widget in Verse.
Before You Start
Before you start, complete these steps:
Read the following documentation to learn the basics of how to create a custom button menu:
How to style and organize widgets in the widget graph.
How UI Materials work.
How to create a User Widget.
Animating UI tutorial.
Create a copy of the User Interfaces template (Documentation: User Interfaces Feature Template) and open the UW_CustomButton widget to learn more about the following topics:
How to use the Custom Button widget.
UI animations.
How to bind Custom Buttons.
UMG Button Types
UMG has different button options that offer varying degrees of customization.
UMG has different types of buttons that you can create: UEFN buttons and Custom Buttons. Each button type offers varying degrees of customization.
UEFN Buttons
UEFN Buttons are common buttons that borrow their style and functionality from Fortnite. You can find UEFN buttons in the Palette menu under Palette > User Created. See the table below for the available UEFN buttons.
| Button Name | Description | Image |
|---|---|---|
Quiet Button | A small-sized button with a small font and a translucent background. | |
Loud Button | A mid-sized button with a large print and yellow background. | |
Regular Button | A large-sized button with large print and a translucent background. |
All UEFN buttons share the following functionality:
Animated background
Button sounds
Editable text
Input methods
Selection states
Custom Buttons
Custom Buttons do not have predefined behavior. Instead, you customize Custom Buttons to fit your needs. For example, you can create a Custom Button menu UI that a player triggers when they interact with an inventory or a map. You can find Custom Buttons in the Palette menu under Palette > Common.
Animate a Color Change
If you followed the Animating UI tutorial (Documentation: Animating UI) listed in the Before You Start section on this page, you learned how to add widgets to Sequencer, animate a widget’s visibility, position, scale, and more. You’ll build on those skills to create oscillating button icons and text as found in the Custom Button example in the User Interfaces template. You’ll also change the button widget’s color.
To animate a widget’s color, you must target the widget’s linear color channels and then keyframe the R, G, B, A values to create a shifting color gradient. For example, in the Custom Button example in the template, the MI_UI_Battle_Button button’s material instance has the ColorFill, ColorShadow, and ColorStroke parameters targeted for animation.
Follow these steps to animate the color for a widget:
Add the Brush.Brush Material to the Sequencer Hierarchy stack.
This does two things: it provides a way for you to add the material instance’s individual color parameters to the Hierarchy stack, and adds the material and its parameters to the timeline.
Open the ColorFill parameter in Sequencer to see the color channel values.
Open MI_UI_Battle_Button and select the ColorFill parameter color field.
You’ll see that the channel values for the parameter are the same as the channel values in the Hierarchy panel when the playhead is at the start of the animation.
Move the playhead to the end of the animation sequence and set a keyframe.
Change the values for the R, G, B, and A channels to match the color you want to end with.
Save your changes.
Move the playhead between the first and second keyframes to see the color values shift.
Repeat the steps above for each asset that you want to change the color values for.
Custom Button Layout
Use the Custom Button widget to design unique buttons and program them for your game. In UMG, you design the layout of your Custom Button in the widget hierarchy. This determines which layer each widget appears on.
In the image below, the example UW_Custom Button widget is built and structured in the Hierarchy panel.
Note the following key elements of the Custom Button layout in the image above:
Grid Panel: Contains all of the button widgets.
Button 1: The Custom Button widget, nested inside the first Grid Panel.
The visual elements that make up the button: icons, stroke around the button, and text.
Button Materials and Icons
The button materials and icons (widgets) that make up the layout of UW_CustomButton use assets that you can find in the Material Instances, Materials, and Textures folders listed in the template under UserInterfaces > Verse > CustomButton. Search the folders for the following assets:
M_UI_Battle_Button
MI_UIButton_Battle
MI_UI_Button_Box
MI_UI_Button_NewGame
MI_UIButton_Settings
T_Icon_Battle
T_Icon_NewGame
T_Icon_NewGame1
T_Icon_Panel
T_Icon_PanelS
Copy the material and icon assets from the UI template into a new project and change their parameters to add new colors and functionality to learn how they work.
The example uses the M_UI_Battle_Button material to create the four material instances listed above. Open each material instance to see the parameters that can be exposed in Verse. Verse-exposed parameters are targeted during animation to control the color of the textured lines in the material, the size of the button shadow, the offset of the material, and all the button color parameters.
Check additional parameters in the material instance to expose them for targeting and animation.
The button material (M_UI_Battle_Button) has two mask effects, horizontal lines and halftone circles that appear in the right-corner of the material. The halftone mask is hidden when the button is in its default state. When a player hovers over the button, the halftone mask fades into view to reveal itself.
Take a look at the UI Sequencer to see how these animations were built.
Bind Button Animations to Player Actions
To make a button’s animation play, you must first bind the button’s animation to a player action. This example binds the Custom Button’s animations to the following player actions:
OnHighlight: Change the button’s appearance and play an oscillating animation.
OnUnhighlight: Change the button’s appearance back to its original state and stop playing the oscillating animation.
OnClicked: Close the button menu.
Follow these steps to add the Custom Buttons to the View Bindings window:
Select Button1 (Custom Button widget) in the UMG Hierarchy panel.
Click View Bindings on the bottom toolbar to open the View Bindings window.
Click +AddWidget to add the Custom Button widget to View Bindings.
Repeat the steps above to add widgets to the View Bindings window that need to be bound to player interaction. Then, follow the instructions in the sections below to bind the animations to the player actions.
Bind the OnHighlight Appearance Animation
In the View Bindings window, select the left field > Button1 > OnHighlight > Event. This binds an OnHighlight event (player action) to the button.
Select the right field > UW_CustomButton > Queue Play Animation Forward > Select. When the player hovers over the button this binding triggers the animation that causes the button to change its appearance.
Select the Link icon next to the In Animation field.
Select the empty In Animation field and select UW_CustomButton > Anim_Button1_Highlight to bind the animation to the OnHighlight event.
Add 1.0 to Playback Speed to play the Anim_Button1_Highlight animation forward at 1x the speed (in real time).
This animation changes the Button1 highlighted appearance when the player hovers over it.
Bind the OnUnhighlight Appearance Animation
Select the left field > Button1 > OnUnhighlight > Event. This binds an OnUnhighlight event (player action) to the button.
Select the right field > UW_CustomButton > Queue Play Animation Reverse > Select. When the player hovers over the button this binding triggers the animation that causes the button to change its appearance.
Select the Link icon next to the In Animation field.
Select the empty In Animation field and select UW_CustomButton > Anim_Button1_Highlight to bind the animation to the OnUnhighlight event.
Add 1.0 to Playback Speed to play the Anim_Button1_Highlight animation in reverse at 1x the speed (in real time).
This animation reverses the button back to its original state when the player stops hovering over the button.
Bind the OnClicked Close Menu Animation
Select the left field > Button1 > OnClicked > Event. This binds an OnClicked event (player action) to the button.
Select the right field > UW_CustomButton > Close Event. This closes the menu when the player clicks on the button.
This closes the button menu when the player clicks the button.
Bind the OnHighlight Oscillating Animation
Select the left field > Button1 > OnHighlight > Event. This binds an OnHighlight event (player action) to the button.
Select the right field > UW_CustomButton > Queue Play Animation > Select. When the player hovers over the button this binding triggers the oscillating animation.
Select the Link icon next to the In Animation field. The icon turns blue.
Select the empty In Animation field and select UW_CustomButton > Anim_Button1_Loop > Select to bind the animation to the OnHighlight event.
Add 999 to Num Loops to Play. When the Anim_Button1_Loop animation plays, it loops 999 times while the player is in the OnHighlight state.
Set Play Mode to Forward. This plays the animation forward.
Add 1.0 to Playback Speed to play the Anim_Button1_Loop animation forward at 1x the speed (in real time).
When the player hovers over the button, the animation oscillates the button back and forth.
Bind the OnUnhighlight Oscillating Animation
Select the left field > Button1 > OnUnhighlight > Event. This binds an OnUnhighlight event (player action) to the button.
Select the right field > UW_CustomButton > Queue Stop Animation > Select. When the player stops hovering over the button this binding causes the animation to stop.
Select the Link icon next to the In Animation field.
Select the empty In Animation field and select UW_CustomButton > Anim_Button1_Loop > Select to bind the animation to the OnUnhighlight event.
The animation stops playing when the player stops hovering over the button.
After you bind your button animations to the player actions, you’ll add Verse Fields to the Custom Button next. Verse Fields creates variables for the Custom Button that you can call in Verse script to play the animations that you’ve bound.
Create Verse Fields
In UMG you can add Verse Fields to a User Widget. This lets you call code in your Verse script to play the animations that you’ve bound.
To create a Verse Field, follow these steps:
Click +Add in the Verse Fields panel to add a Verse Field.
Name and field type: The name should reflect the mutable you’re creating.
Mutability: Specify whether the Verse Field is a variable or a constant.
Has Default Value: Specify whether the Verse Field has a default value. You can turn this on and off.
Attributes: Specify what object the variable belongs to. You can add a category and tooltip to the attribute.
The Custom Button example uses two Verse Fields: CloseEvent and TriggerIntro. These Verse Fields are explained in more detail below.
CloseEvent
CloseEvent is a constant you select from the custom binding list to close the button menu when the player clicks a button. See the Bind the OnClicked Close Menu Animation section above. In the Verse script, an OpenMenu() function subscribes to the widget’s CloseEvent binding. This ends all animations and closes the button menu.
TriggerIntro
TriggerIntro is a variable available from View Bindings, but used in the Verse code to trigger the text widget animation of the menu name, CUSTOM BUTTONS. The variable uses logic to determine when to play the animation on the widget and the duration the animation plays.
Custom Button UMG Device Example Code Overview
You can use Verse Fields and exposed widget bindings to do the following:
Play animations.
Open and close individual widgets.
Open and close the user widget.
In the Custom Button example from the UI template, the UI is designed in UMG. The Custom Button example uses Verse to do the following:
Add devices, widgets, and players to the HUD.
Set up events that open and close the menu.
The code for the Custom Button example is explained in detail below.
To begin, the example includes the following module imports at the top of the script:
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Simulation }
This lets you access the UMG widgets and their properties in the Verse script, and also determine a location on the HUD to display the UI.
The example also places a Volume device in the viewport. Note that its Visible in Game setting is turned on to make the volume visible during playtesting. The Verse script also references the volume device.
Define the Custom Button Class
The custom_button_umg_device class uses:
An editable Volume device as the trigger for the menu.
The user widget for the menu design and its exposed bindings to determine when to open and close the menu.
Two variables to search for the current player and subscribable events.
The
volume_devicebecomes an editable device namedShowVolume.The class calls and references the
Widgetin order to add the player’s UI. The expression uses theUW_CustomButtonuser widget to expose the widget’s bindable propertiesTriggerIntro,TabIndex. andCloseEvent.TabIndex is a default user widget property.
VerseWidget : UserInterfaces.Verse.CustomButton.Widgets.UW_CustomButton = UserInterfaces.Verse.CustomButton.Widgets.UW_CustomButton{}Two variables are used to search for subscribable events and players. The first variable is named,
var Subscriptionand the second onevar CurrentPlayer.The
var Subscriptionvariable searches for?cancelable_eventand returns false if it finds an event that isn’t cancelable.The
var CurrentPlayervariable searches for?playerand returns false if the player is not the current player.Versevar Subscription : ?cancelable_event = false var CurrentPlayer : ?player = false
Set Up Player Events
Next a series of functions are used to set up the player events that trigger the menu to open and close.
The
OnBeginfunction listens to theShowVolumedevice’sAgentEntersEventand subscribes to theOnAgentEnteredevent. This event searches the scene and determines whether theAgent(player) entered the volume or not.ShowVolumesubscribes to the Volume device’s subscribable event functionsGetPlayspace()andPlayerRemovedEvent(), then subscribes these events toOnPlayerLeft.The function
GetPlayspace()searches the scene for the player in order to add the UI to the player’s game space.The function
PlayerRemovedEvent()searches for the player and determines whether the player was removed from the scene or not in order to close the menu and to reset the menu.VerseOnBegin<override>() : void = ShowVolume.AgentEntersEvent.Subscribe(OnAgentEntered) GetPlayspace().PlayerRemovedEvent().Subscribe(OnPlayerLeft)A new function named
OnAgentEntered(Agent : agent)listens for players in the level and searches the scene for a player (Agent) entering the Volume device.An
ifstatement searches forPlayer := player[Agent], then a second if statement searches forCurrentPlayer. When theCurrentPlayeris found, the function returns theOpenMenu(Player)function.VerseOnAgentEntered(Agent : agent) : void = if (Player := player[Agent]): if (CurrentPlayer?): return OpenMenu(Player)The function named
OnPlayerLeft(Player : player)listens for the player leaving the volume.An
ifstatement searches forExistingPlayerand checks to see if that isCurrentPlayer?. And ifExistingPlayer = Player, then theCloseMenu()function is called.VerseOnPlayerLeft(Player : player) : void = if (ExistingPlayer := CurrentPlayer?, ExistingPlayer = Player): CloseMenu()
Open Menu Functionality
The OpenMenu function takes a parameter of player type ( a player in the game). First the function tries to obtain the PlayerUI class under the player. If successful, it sets the focus on the player input to the Widget constant declared above, then adds Widget to the PlayerUi class. This sets the input mode to All so the player can interact with the widget.
The
OpenMenu(Player : player)function uses an if statement to determine whether to executePlayerUI := GetPlayerUI[Player]):.based on where the player is.A function named
PlayerUI.SetFocususes Widget to call the user widget.Another function named
PlayerUI.AddWidgetaddsWidgetto the player’s UI slot usingInputMode.VerseOpenMenu(Player : player) : void = if (PlayerUI := GetPlayerUI[Player]): PlayerUI.SetFocus(Widget) PlayerUI.AddWidget( Widget, player_ui_slot{ InputMode := ui_input_mode.All } )The UW_CustomButton user widget displays in the HUD and added to the player’s play space using specifiers that access the
WidgetandPlayer.Verseset Widget.TriggerIntro = true set CurrentPlayer = option{Player}Lastly, an expression named
SubClosesubscribes toWidget’sCloseEventandOnCloseEventfunctions. Then determines the user widget’s visibility based on the subscription toSubClose.VerseSubClose := SubscribeToEvent(Widget.CloseEvent, OnCloseEvent) set Subscription = option{SubClose}
Close Menu Functionality
The OpenMenu(Player) function subscribes to two functions named OnCloseEvent() and CloseMenu(). These functions listen for the player interacting with the buttons that result in closing the player menu.
The
OnCloseEvent() function calls the second function,CloseMenu().VerseOnCloseEvent(Args : tuple()) : void = CloseMenu()The second function,
CloseMenu(), checks if the Player triggering this function has a player UI containing theWidgetconstant. If it does, it removes the widget from this player’s PlayerUI class.VerseCloseMenu() : void = if (Player := CurrentPlayer?, PlayerUI := GetPlayerUI[Player]): set Widget.TriggerIntro = false PlayerUI.RemoveWidget(Widget)Setting
TriggerIntroto false acts as a failsafe or reset to ensure that ifWidgetis added to the player again, the intro animation can be triggered again.The specifier set
Widget.TriggerIntro = falseuses the user widget’s bindableTriggerIntroproperty to monitor the player interactions and determine to close the menu or not.The function
PlayerUI.RemoveWidget(Widget)removes the user widget whenCloseMenuis called.A second if statement queries whether
SubClose := Subscription?returns false on theOnCloseEvent, then it calls theSubClose.Cancel()function.Lastly, two specifiers determine whether
Subscriptionis false andCurrentPlayerisfalse. This returns false if the player left the volume, or the player clicked a button and closed the menu.Verseif (SubClose := Subscription?): SubClose.Cancel() set Subscription = false set CurrentPlayer = false
Complete Code
# Copyright Epic Games, Inc. All Rights Reserved.
using { /Fortnite.com/Devices }
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Simulation }