Download

Improved Keyboard/Gamepad Input & Widget Focus Handling for UMG Menus

2nd feature.That’s why I got here.I can’t do that at all.

Hey how about this?Снимо1к.PNG

Looks interesting. It’d be great to see that in action @Silêncio… Any chance of a Video etc?
I often give up on focus. Just accept inputs to everything / filter using Gates + Game-States.

Looks interesting… It’d be great to see that in action @Silêncio… Any chance of a Video etc?
I often give up on focus. Just accept inputs to everything & filter using Gates + Game-States.

99% of the time the issues with focus that people have are because widgets that you don’t want to be focusable often are. Make sure you uncheck the bIsFocusable flag in Blueprint, and set the widget visibility to something non-hit testable. Both are things you should do anyway really while building the widget.

Good evening, first of all with the focused and unFocused events the problems of making widgets with gampad or keyboard would be solved very much.

I’ve been a programmer for some time (Delphi, java, c ++ … = but it’s the first time I’ve programmed a videogame and use unreal engine 4.18.

After a lot of reading through forums and not getting much … I have come up with a solution that I think is elegant that I am using (until we have the onFocus and onUnFocus events) and I wanted to share it with you …

The code consists of the following_

Step 1: I enter manually All widget buttons in an array in the begin play event

In my case they are always inside a vertical box

Note: I do not think there is an array with all the elements of the widget, it’s a pity because it would be very useful

Step 2: In a tick event I use a loop I check if the button is focused with a branch.

If this focus changed the normal style “imitating” hovered and if it is not, change to normal style

Step3: To not have the sound in loop I use a doOnce event that is reset each time the style is changed to focused with the variable focused

The integer variable “focused” saves the last element “focused”, if the variable changes, it resets the doOnce function

Note1: The UnFocusButton function is simple because my buttons are transparent

Note2: I’m sorry for my english … it’s very bad


Buenas noches, antes de nada con los eventos focused y unFocused se solucionaría mucho los problemas de hacer widgets con gampad o teclado.

Soy programador desde hace tiempo (Delphi, java, c++…= pero es la primera vez que programo un videojuego y uso unreal engine 4.18.

Después de mucho leer por foros y no conseguir gran cosa… he llegado a una solución que me parece elegante que estoy utilizando (hasta que tengamos los eventos onFocus y onUnFocus) y quería compartirla con vosotros…

El código consiste en lo siguiente_

Paso 1: Introduzco manualmente Todos los botones del widget en un array en el evento begin play

En mi caso están siempre dentro de un vertical box

PD: Creo que no existe un array con todos los elementos del widget, es una lastima porque seria de gran utilidad

Paso 2: En un evento tick utilizo un loop compruebo si el boton esta focused con una rama.

Si esta focused cambio el estilo normal “imitando” hovered y si no lo esta, cambio a stilo normal

Paso3: Para no tener el sonido en loop utilizo un evento doOnce que es reseteado cada vez que cambia el estilo a focused con la variable focused

La variable integer “focused” guarda el ultimo elemento “focused”, si la variable cambia, resetea la funcion doOnce

PD1: La funncion UnFocusButton es simple porque mis botones son transparentes
PD2: I’ m sorry por mi ingles… es muy malo

I never understood the focus in UMG, in the end I decided to create a custom UserWidget with a focus and lost focus custom delegates, all my widget inherited from this, and then when I receive inputs I look for all widgets of this class and only those marked as focusable, then by comparing their screen absolute position with the one in focus I was able to determine if something is focusable for the axis, let say if it was nothing at right then is not possible lost my focus, but if it was, then you can focus something new and broadcast the delegate for every widget,

Probably not the smart idea ever, but it does the job!

And why? because for that project I expended 2 days dealing with my widgets just in a effort to use properly the focus feature inside UE, but in change I expended just 1 day to implement my own,

I agree with the guy who began this thread, UMG is powerful but some stuff like this is confusing, not hard but confusing enough for me to create my own

I added this function to track widget focus in Ticks which is super gross/not optimized, but it makes for some WAY cleaner HUD blueprints.


UWidget* APFPlayerController::GetCurrentWidgetFocus()
{
    for (TObjectIterator<UWidget> Itr; Itr; ++Itr)
    {
        if (Itr->HasUserFocus(this))
            return *Itr;
    }

    return nullptr;
}

Here is a brief description of my implementation.
For me, Focus means Hovered. same thing. So I edited SWidget.h to do that.
was a very simple change.



    /** @return True if this widget hovered */
    virtual bool IsHovered() const
    {
        return bIsHovered || HasKeyboardFocus();
    }


Keyboard focus is the same for gamepad as well so this works. My buttons then get the Hovered Style through navigation provided I set the User Focus to a button. I made my own subclass of UUserWidget to manage focus, at well as addition and removal from the screen. This class keeps the last focused element. It’s important in large UMGs to call focus when you show and hide panels, but otherwise nagivation works well.

in the Player controller I created an array of Widgets in a sort of stack (it’s not really lifo because you could remove something that’s not at index 0). and this is called by MyUserWidget. This allows me to automatically set the user focus back to the last focussed objects if I close a popup, or if I click outside the area with the mouse. We assume the player doesn’t want to see focus at this point and focus is lost so everything works for them.

in MyGameViewportClient (subclass of GameViewportClient) I override InputAxis and InputKey which allows me to check if I pushed a gamepad or keyboard. This sends a message to my player controller which will refocus on the last element based on the Widget on top of my stack.

Hope that helps and I’m always ready to talk about it if you have questions or share some code.

If you don’t want to mess with engine code, you can re-implement your own button widget entirely using a UserWidget and add your own focus handling logic. It’s a pain, unfortunately. There should be more exposed controls over focus handling logic. For an engine that focus consoles, it’s a shame every dev has to hack together their own gamepad navigation code.

Oh good. I thought I was being dumb for hacking together my own gamepad navigation because I just couldn’t figure out how to use the built in stuff.

I see from the previous comments that there may not be an easy solution to this, but I’m hoping there’s a Blueprint solution that I’m overlooking.

As shown in the first image, I have a Main Menu that starts with the focus on the “Play” button from which the player can navigate with arrow keys down to select the other buttons.

As shown in the second image, pressing the “Option” button opens a different Options Menu widget with focus set on the “Video” button. However, when exiting this menu to reveal the Main Menu underneath, I cannot restore focus back to the “Play” button. *Note: When navigating with arrow keys the focus/navigation occurs on both in the Options menu in front as well as the Main Menu beneath. That is to say all focus has not truly shifted solely to the Options Menu when opened to conceal the Main Menu.

I’m not sure if this is possible. If not, I was hoping as a workaround to destroy the Main Menu widget beneath and recreate it upon exiting the Option Menu with the focus set to “Play” upon event construct. Unfortunately I have not been able to accomplish this either.

Any help with the proper way to fix this or even an ugly workaround would be greatly appreciated.

It’s annoying, yes. If you need keyboard/gamepad navigation, do not use the Button widget directly on your screens/windows/popups, period. The same goes if you are making any game with more than a couple screens: manually setting up each button scales very poorly and going back and re-styling them is a major time sink.

Create your own custom button by creating a Widget Blueprint that implements and forwards the events you need using dispatchers (you can use a button as the root widget to re-use most of the functionality) and use the PreConstruct event to make it behave as WYSIWYG in the editor. You can then make all your buttons follow the same style rules, already contain the text field (with the text being set using an editable property) and most importantly: you can add the focus received and focus lost events to it and display focus as you see fit. You can even use animations instead of brush swapping for button state changes.

Thanks for the reply. Having difficulty using this with a menu system I got from the Market Place… I will try this later from scratch, but it will be a while.

100% agree.

Brilliant! This is an excellent quick fix/hack for solving the “focused” styling problem. You inspired me to make this change in SWidget.cpp, as well, to make focus events trigger hover events.

!!!WARNING!!! I know, hacky af…but works for my use case and is what I’ll be doing until Epic finds a cleaner solution.



FReply SWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& InFocusEvent)
{
    //-----------------------------
    // CUSTOM CODE
    FPointerEvent MouseEvent;
    OnMouseEnter(MyGeometry, MouseEvent);
    //-----------------------------

    return FReply::Unhandled();
}

void SWidget::OnFocusLost(const FFocusEvent& InFocusEvent)
{
    //-----------------------------
    // CUSTOM CODE
    FPointerEvent MouseEvent;
    OnMouseLeave(MouseEvent);
    //-----------------------------
}


I’m doing something very similar to handle navigating between menus and losing focus due to clicking outside the window.

The vast majority of problems with UMGs focus could be resolved with a simple “lock focus” option that makes a widget remain focused no matter what you do until that bool is manually cleared.

Wooh, this is one of the most helpful pages I found on UMG so far…

Well, if I may suggest. I think the official documentation could be quite improved on that part. There are a lot of things that are not explained anywhere and you end up retro-engineering stuff to get some grasp about how they are supposed to be used.

For example, it took me hours to manage making any kind of databind to some listview entries : it took me forever to find that the entry needed to implement IUserObjectListEntry and override the SetListItemObjectInternal function (for me, “Internal” means that I should not be messing up with it). Well maybe there are other ways, but I literally spent hours on the official documentation and forum topics without finding it explained anywhere.

It’s been three years. Any progress on this?

I get your technical explanations, and that Unreal Engine users are expected to be technical, but as others have mentioned, from a indie user’s perspective, it’s rather silly that there has to be a difference between hover and focus. If a user wants to treat it the same, that should be an option.

It seems really silly to have to enable tick on the widgets and check for focus (and still not be able to call hover manually), especially since there’s animation timelines for widgets now.

EDIT: Here’s my workaround which really should not be necessary at all…

“Master” class:

“Instance” class:


I mean, GetAllWidgetsOfClass can’t even select the default “button” class widget so you can’t ever automatically list all buttons, you have to drag them out manually for each and every menu in the entire game… :frowning:

I’m a newbie so I really hope I’m wrong… but for example, I made a mistake animating the transforms on the focused button earlier (this apparently causes gamepad navigation to semi-randomly fail for some reason) and searching for umg & “set render transform angle” yields literally two results, one of them a python example and one of them chinese… zero tutorials, zero examples and the documentation seems to be auto generated with no added value.

While I’m at it, the tick thing is just weird, because I have ticks disabled by default in the project settings, and there wasn’t any enable tick in the class settings for UMG, and no method to set it with. Apparently UMG ticks by default even though it’s disabled project wide? Plus, a tangent on this, everyone seems to say to NOT bind variables, because that causes UMG to tick like crazy which is bad. Why was it designed like this?

Anyway, I really hope Epic steps up in this area.

@NickDarnell hey, this thread is now more than 2 years old and I didn’t see any improvements in the way the focus is handled.
Did you planned to push something on this or should we stick with custom improvments?
I mainly think about the “onFocus” “onUnfocus” that are pretty easy to push without any side effects but it will helps us a lot.
Having to build the engine just to fix this module is not user friendly.
I hope you can do somehting on this!
thanks,

Something that Just Worked with both keyboard navigation and gamepad navigation would be swell!

Manually wiring up all the navigation graphs and navigation events for gamepad and keyboard and mouse is quite the chore, and so easily breaks when layouts move around :frowning: