For every widget that inherit from WBP_GenericInputHandler, and its sub widgets (example, for a menu its sub widget is a button) you can contextually show or hide certain elements from screen base on the device that you are using (mouse, keyboard, gamepad).
To begin with make sure your menu inherit from the right class, follow this post to learn how to do it.
After that if you select any widget in your menu
in its Details Panel, in the Behavior section you’ll find the Visibility field, on the right side of the value you will bind a box called Bind
if you select one of the functions showed in the list, you are making sure that this widget will only be visible when that device is active, for example if you select GamepadVisibility, it will be visible only when you use your gamepad, you can even specity two devices, like mouse and keyboard.
In a menu with a lot of elements and elements managers you’ll need to focus only the current active element desired by the user, to do it you need to use an Input Focus system that I call Listening.
The algorithm of this system is inside WBP_GenericInputHandler, so any widget that inherit from this class will inherit that logic too.
Main Receiver
In this post I explain how to spawn a widget and how to assign user inputs to it, from that moment it will be the only widget that will receive user inputs, I call it Main Receiver, anything else that want to be update about user inputs will be a Listener of the Main Receiver.
For example a button (Listener) inside a menu (Main Listener) to receive updates about user inputs need to be registered as a Listener.
Listener
A Listener is any element or elements manager that want to be updated about user inputs.
Element Managers which contains other elements will automatically update the active element when they receive an update, for example if you have a list of spinboxes inside a menu, the list is a Listener of the menu, when you select a spinbox inside a list it will automatically become a Listener of the list (so a Listener of a Listener works too), so we’ll have that when a user input is detected by the Player Controller it will be sent to the Main Receiver (which is our menu) which will send it to the List (which is a Listener of the Menu) which will send it to the current selected spinbox (which is a Listener of the list).
There is not an end on the layer of depth that you can have of Listeners, to control them you can use this three simple nodes.
Register Listener
From a widget of type WBP_GenericInputHandler (or any widget that inherit from it) you can call RegisterInputListener() which takes a reference to a widget of the same type as parameter. From the moment it is registered, it will receive all the inputs that the first one receive.
By default you can have multiple listeners to a single widget, but you can easly register a single widget and remove all the others by simply checking the parameter IsExclusiveListener.
Unregister Listener
After registering a listener you can unregister it when necessary by simply calling UnregisterListener() and passing the listener to unregister by parameter. After you Unregister a Listener it will not be able to receive user inputs updates.
Unregister All Listeners
If you want to unregister all the listener of a widget just call UnregisterAllListeners(), this function does not work globally, it refer to the listeners of a single widget.
This function will be automatically be called when you check the IsExclusiveListener parameter in the RegisterListener() function.
The Continuous Call Curves are use to determine the frequency of function calling when a key is held down.
You can find the default curve in /UmgInputManager/Curves/CF_BaseInputFrequency, if you open this asset you’ll see a curve composed by nodes
if you hover a node with the mouse cursor you’ll see that a tooltip will popup
it contains the axes of the curve, Time and Value.
Time: specify the time passed in seconds since the key was pressed, so at this node after 2 seconds that the key was pressed the Value will be 0,2
Value: is the frequency itself expressed in seconds, in this case 0,2 means that the function will be called every 0,2 seconds a this point (or 5 times per second)
To create new input friendly UI elements you need to rember that your new element class must inherit from WBP_GenericInputHandler, or from a class that already inherit from it.
Create From Existing Elements
This is the most common case, where you want to create a customized version of an existing element. Just remember to always inherit from a Generic class, never from Basic classes if you want to learn more about elements types follow this post.
For example let’s say you want to create a button with a new style for your game, to have a reference of how it’s done you could search the basic class of that element, in this case the WBP_BasicButtonasset (remember, it contains the visual style of the button, all the logic is inside WBP_GenericButton).
First off you need to inherit from the WBP_GenericButton, if you want to learn how to correctly inherit from a class follow this post.
After that you can start making the style of your button in the designer widget
when you are happy with it you’ll need to add some basic logic
there you need you specify which visual elements change and how, when cenrtain things happens, for example you need to specify the Selection, Unselection, Click, Activation, Deactivation and so on, to do that look in the function section of the graph
what you need to do is to override those function that we said before, to do that just click the Override button before the +Function button, here you’ll find all the functions that you can override from your class hirerarchy (in this case WBP_GenericInputHandler->GenericElement->GenericButton->YourCustomButton)
let’s override for example the Select function, in the WBP_BasicButton the logic is very simple
never delete the Parent node in an overriden function, it runs the logic in the parent class
use its return value to know what to do, in this example when Select is called it means that something want to select your button, but there are certain policies to respect to select your button, if those policies are all respected then the return value will be true and you can specify what to to, otherwise you can return false as the parent node did
in the case of WBP_BasicButton the selection consist in playing an animation
same thing is done for the Unselect function.
Create A Whole New Element
Let’s say you need a UI element that is not contained in the plugin, to create it you need to understand in which category it falls (if you want to learn more about elements types follow this post).
For example let’s assume we want an input friendly Elements Switcher, which can contains other elements but can show only one at a time, because it can contains other widgets, this means that it is a Elements Manger so you’ll need to inherit from WBP_GenericElementsManager (if you want to learn how to correctly inherit from a class follow this post)
Open you widget after you’ve created it, the first thing to do to make sure it can contain other elements it to add a named slot
which will be exposed in the hierarchy when you use your Elements Switcher in the Hierarchy of a widget.
After that you need to add the logic of your switcher, to do that open the Graph Editor
the first part to add is to specify to the parent classes which is your Named Slot, to do that override the function called GetElementsPanel
in this case you can delete the parent node because it is a NULL reference
replace it with the contet of your named slot
after that you can override functions like Next and Previous if you want to look at examples seach for these assets: WBP_GenericList and WBP_GenericGrid
Then you could configure the inputs & actions relations look a this post to learn more
If you want to customize your mouse cursor you will find a widget that represent it in this path /UmgInputManager/Blueprints/Widgets/WBP_MouseCursor.
Customize Texture
If you open the widget you will see in the hirerachy that there is only one image called mCursor your can edit it as you want
just keep in mind that the point where the cursor interact is in the center, as you see in the image below the tip of the arrow is exactly in the center.
Add Animation
You could even add an animation to your cursor because it works just like a normal widget.
To configure the relation between inputs and actions just go into the Class Defaults (that can be your menu, or a button or a list or every other widget that inherit from WBP_GenericInputHandler.
in the Details panel you will find a parameter called mInputBindings
It is an Array of a custom Structure where every element determine which function to call when a key or a axes changes.
The FunctionName parameter indicates the Function (or Custom Event) that should be called, it must be a function that do NOT have parameters NOR return values otherwise it will not work by engine design, make sure you type the exact name.
The InputType parameter indicates if the functions need to be called when the keys (in the next array) will be pressed or released.
The Keys array parameter contains an array of input keys to consider when one of them satisfy the InputType parameter.
The Analogs array parameters contains a custom structure to configure each analog input.
The Analog parameter contains the raw analog key.
The Rule parameter contains a custom structure to determine when the previous Analog parameter should be considered as changed, the Rule parameter indicates that the value of the analog must be Greater Than or Less Than the Value indicated in the second parameter.
The ContinuousCall parameter determine if the function should be called continuously while the input is satisfied or just called once waiting that it will change again.
The ContinuousCallCurve contains the curve of the frequency used to determine how many times per seconds to call the function as the time passes, if you want to learn how to edit it follow this link.
If you have created your custom Game Instance either in Blueprint or C++ you need to reparent it in a way that can work well with the Game Instance you will find in the plugin’s folder. Find your case in the list below:
If you have created your game instance in Blueprint you can easly reparent it with the one inside the plugin’s folder, to do so just open up your Game Instance and then open the Class Settings
then in the Details panel you will find the Parent Class field, here just assign the BP_UmgInputManagerGameInstance class and you are done.
Game Instance created in C++
If you have created you Game Instance in C++ then you need to reparent the one you’ll find in the plugin’s folder, to do so, locate to the Game InstanceAsset
open this blueprint and then open the Class Settings
then in the Details panel you will find the Parent Class field, here just assign your Game Instance Class created in C++
After that open up your Project Settings
Open the Maps and Modes category in the left column
In the Game Instance Class field just assign BP_UmgInputManagerGameInstance and you are done.
Game Instance inherited in Blueprint from C++
In this case just follow the previous steps in the following order:
In this post you will learn the right way to spawn a widget in blueprint. I want to clarify that this is a generic example, we’ll spawn the widget in the level blueprint so that when you play your game you will immediatly see the spawned widget, except for that you could spawn it when you want and the way you want.
First step, open up your Level Blueprint by going to the Blueprints button in the toolbar above your viewport
then click Open Level Blueprint
as said, we will use the Event Begin Play that will be called immediatly after you play the game
to this event connect the Create Widget node
Click the Select Class and choose the menu that you want to spawn, in this example we will spawn the WBP_Sample
now assign the Return Value to a Variable of the same type
now your widget is created in memory but is still not visible in the viewport, to show it in your screen you need to call the node Add To Viewport
now that is visible you finally need to assign user inputs to this widget, to do that you need to call from your Player Controller, Set Input Mode UI Only
now if you hit Play you should see the Sample menu and you should be able to interact with it.
UI elements are subdivided into two macro categories: Elements and Elements Managers. The first category contains those UI elements such as buttons, checkboxes and so on, the second category contains those elemens that manages other elements such as lists and grids.
This is the very base class of UI Element such as buttons, checkboxes and so on. This macro category contains two sub categories, Generic Elementsand Basic Elements.
This class has the logic of a spinbox, it can clamp the value between a minimum and a maximum, it can increment or decrease by a specific delta and it can show a minimum and maximum value of fractional digits.
This class has the logic of a text spinbox, it can contain an infinite number of entries, but show only one at a time.
Basic Elements
This classes instead of the previous ones doesn’t directly inherit from WBP_GenericElement but inherit from one of the above classes, they are the visual representation of the logic of that classes