Community Tutorial: Common UI Plugin - Keyboard Navigation

Common UI is a great Plugin; however, the documentation is sparse right now and people are having issues with Keyboard Navigation. I managed to get Keyboard Navigation to work! This Tutorial explains my clean(ish) implementation.

https://dev.epicgames.com/community/learning/tutorials/B5R6/unreal-engine-common-ui-plugin-keyboard-navigation

7 Likes

Hi,

It would be great if you did a video version of this because I’m really having trouble with hovering keyboard, Gamepad and mouse navigation.

1 Like

I followed trhe guide and everything works great except the Confirm input action. For some reason it just doesn’t work.

I defined a “Confirm” input action in my table and bound it to Enter on the keyboard but it just doesn’t work.

2 Likes

Did you set the Triggering Input Action for your Button to Confirm? In your Widget Blueprint, with your Button selected, the Triggering Input Action should look as mine does in the picture at the bottom of the Tutorial.

Thanks for the idea springboard. For what it’s worth, while I’m having no luck get things to look selected (everything matches your setup, afaict), the hovering is working nicely. Also, so far, focus is interchangeable between all 3 input types, every time I’ve tested it, though there’s occasionally like a hitch when swapping between them too fast. (i.e gamepad will move from last hovered mouse button, and keyboard will move from where gamepad left off, and mouse can hover anything, but appears to start from last hovered… I think. Part of that hitch thing. It seems more like they just aren’t reading where they are until you move, except the mouse, which sometimes reads immediately, and sometimes has to focus a new button. At least in my testing.) Hope that’s somewhat helpful regarding your note near the Set Keyboard Focus node.

1 Like

If you want a Button to be Selectable, be sure to fill out the Selected section of your Button Styles. My Buttons for selecting a Server or Remapping Key Bindings use these Styles:

image

Of course, the Selectable checkbox will need to be enabled in the Button’s settings.

I haven’t worked on the TODO note any further since making the Tutorial! I’ll likely need to dig into CommonUI’s code and find how Gamepad inputs are managed. There must be some state or reference deep down to track the last UI Element the Gamepad was “hovering”. Making the Keyboard and Mouse update this state/reference will fix it! In the grand scheme, it’s a pretty small detail.

1 Like

Yeah, that was poor wording on my part, haha.
I meant they never look pressed. They are firing, just not updating in appearance. I assume that I customized something, somewhere, that is messing with that, though. Kinda doing a whole UI overhaul using Lyra as a model, and it’s hard to keep track of what that changed in addition to what I changed on top of that.

Kind of compounds that whole “sparse documentation” thing.

You know how it goes…

1 Like

Hello, thanks for the great tutorial. Focusing is working, but I have problems with Input Action Confirm. Please help me.

  1. It works only in case when I’ll click with the mouse button at WBP_UiButton. At this point, Enter is working. But. Also works Spacebar but this key I don’t have bond anywhere.
    I need to unbind Spacebar.

  2. When I will select another button by the arrow key, Confirm does not work (Event “On Button Base Clicked” didn’t call). It works again when I click on the Button with the mouse.
    I need to have correct navigation by the keyboard.

  3. I need to bind navigation to W, A, S, D keys.

  4. What is strange, if I remove “Input Data” from “Project Settings” and also from Button->“Triggering Input Action”, Enter and Spacebar are still working.

Thanks a lot for any suggestions to fix it.

2 Likes

I didn’t realize Spacebar works as a “Confirm”! That’s interesting. There are some additional navigation rules like Tab and Shift + Tab going to the next Button and previous Button respectively. I wonder if these are documented somewhere!

For #2: make sure the Default Triggering Input Action is set on the CommonUI Button (both in the WBP, and in the Menu containing instances of the WBP as updating the Blueprint doesn’t always update existing instances). Also make sure the Triggering Input Action is set in the “On Focus. . .” Events in your Blueprint. Both of these are hopefully clearly explained in the Tutorial!

For #s 1, 3, and 4: Unreal has some navigation rules coded outside of the CommonUI Plugin. To unbind Spacebar, you’ll have to write some C++ to override these rules. Binding W, A, S, and D to navigation would likely also need to be done in C++. I haven’t looked into this very much, but FNavigationConfig’s Constructor looks like a promising place to start. Also, FNavigationConfig::GetNavigationActionForKey() appears to be where Enter and Spacebar are “bound”. (Filepath: UE_5.1\Engine\Source\Runtime\Slate\Private\Framework\Application\NavigationConfig.cpp).

I suppose there may be an alternative approach - like consuming Spacebar inputs before they are passed down to Slate, effectively “unbinding” it. Maybe a “dummy” CommonUI Action could be bound to Spacebar and it be set to consume the input? Hard to say without testing!

I have the same problem when i pause the game. Escape button doesn’t work when I enable the widget. How can I activate the escape button?

Have you found a solution?

I am in a slightly better situation now. I changed CommonButtonBase to CommonBoundActionButton and derived it into my Button. I added it to CommonActivatableWidget. When I activate CommonActivatableWidget, the triggering actions start working.

Navigation also starts working with CommonActivatableWidget, along with arrows. I disabled/edited the arrows in the derived C++ class from FNavigationConfig. Now, in the constructor, you can change the binding, as in FNavigationConfig. You can set it in c++:

FSlateApplication::Get().SetNavigationConfig( MakeShared<FMySlateGameNavigationConfig>() );

I have found out that it does not matter if you have set “Input Data” in Project Settings. It is just a default property that will be added to Triggering Actions when you create a widget.

However, I am still working on understanding other things in CommonUi.

4 Likes

I have followed your tutorial but I am facing a wall with commonUI:

1- Right now it does not matter which keys i set on the input data for default click and back actions, click is always space and none of the keys I set up work, only the default one for click, this happens to me both in the gamepad and keyboard. It must be a bug. So i can only move with arrow keys and select with space.

2- When i set focus on a button with the “setFocus” or “setKeyboardFocus” upon widget activation I can not select the button with the space bar, I can only select it after I have moved once with the arrow keys and the blue outline appears around the key (i haven’t disabled the render focus for testing purposes). So at the very beginning of opening and activating a widget the focus is set into a button but i can not select it until I move.

And yes I have checked all the default triggering actions in the screenshots shown in the guide.

I have the same issue, I am pretty sure everything is setup correctly but if I have different buttons, the one that is setup as default does not get pressed until I move around the button list first.

Did you find any solution?

I don’t know if it helps, but I have come with another solution for the keyboard OnHovered behavior using SetSelectedInternal when add/remove from FocusPath. I think it is more simpler, you only need to set the Normal Hovered and Selected Base with the same brush and Normal/Selected Pressed so it behaves the same way.

Blueprint

3 Likes

In my case, all your setup worked perfectly, except for the confirm button, I had it set up on Enter and it seems to only work using Space Bar. Do you have insight on this by any chance?

Edit: Also, I can see that if the mouse is still hovering another button and I use the arrow keys, not both will be set as “hovered”, yes Space Bar only works on the one I move to with the arrow keys, but It could cause confusion.

I know this Topic is some older one… but…
I managed to make the Buttons get hovered by the keyboard keys…
Nice…

But… when i hover one with the mouse and tap a keyboard key… i have two hovered buttons…

And… how can i set a Button to be focused on startup of my Menu? I tried to SetFocus and SetKeyboardFocus inside the EventOnActivated, getting the focused Widget via the overridden GetDesiredFocusTarget Function… but the first button (is set inside the function) is not selected and hovered… i still need to hover it with the mouse first, in order to have keyboard cursor input working…

1 Like

I’ve had the same issue as you where the input data doesn’t make a difference. I’ve also had the weird behavior where I would have to move selection with the keyboard before space bar works. Hitting tab makes it focus to the current button correctly (subsequent tabs move the focused element).

I currently have a work around using OnKeyDown and listening for a space bar input

This calls a c++ method in my derived UCommonButtonBase that calls HandleButtonClicked()

===

Also, Common UI docs were updated. If anyone is looking to change the arrow key or space bar behaviors, the “Customize Navigation in Your UI” section here is useful

1 Like

This worked for me. There is a weird bug though. Let’s say I hover with mouse and then press the keyboard key, the hovered button is still highlighted. Now I have 2 hovered buttons. I think @BDC_Patrick is referring to the same issue

Please base on your tutorials. What was “Default Input Action Row and Null Input Action” set as? You did’nt Show thier Default value. @Patterson

@Aloys005

When creating the variables, do not set a value for either. Default Input Action Row is used in Event OnInitialized to keep a reference to the Button’s default setting and Null Input Action is used in the same Event to set the Button’s Triggering Input Action to nothing.

The Button should have a Triggering Input Action set to whatever value you desire and this must be set both in the Button’s Blueprint and any instance of the Button in a Widget Blueprint (i.e., updating the Button’s Blueprint doesn’t seem to update the settings in existing Instances).

The flow is:
-Button is added to a Widget Blueprint and its Triggering Input Action is set to whatever is desired when the Button is Hovered by Mouse or by Keyboard.
-On Runtime, Button is Initialized and its Triggering Input Action is stored in Default Input Action Row and set to Null. It won’t respond to Inputs when it isn’t Hovered.
-Button is Hovered by Mouse or Keyboard and its Triggering Input Action is set to the Default Input Action Row. It will respond to Inputs.

This is how only one Button - the Hovered one - will respond to an Input.