Make controller capture UMG slider

I have an UMG menu with some sliders. The sliders can be focused with the controller just like buttons. However, in order to modify the value, by default Unreal makes that after you focus a slider, you need to press A to make the controller capture the slider, then you can use the joystick or D-pad to modify the value. I would like to skip this step of pressing A and having that the moment you focus a slider, it gets automatically captured by the controller. Is there any way of doing this? I’ve been checking the API of the USlider class and there is no reference to the controller capture other than the event callbacks, and the player controller doesn’t seem to have anything about captured sliders either. Any idea?

1 Like

The scroll box is a notoriously uncooperative element. A somewhat similar scenario is being discussed here:

tl;dr: expose the scroll box as a variable and set its offset directly or have it scroll to the next child, which is most likely preferable when not using analogue controls.

Thanks for the answer but my question was about sliders, not scroll boxes.

I tried a similar approach but get the problem that Unreal does not repit input events as windows does, so you have to press the button multiple times to change the slider multiple times, you can’t hold. I suppose I can simulate the input event repetition myself, but that was the part I was trying to avoid since Unreal already implements it correctly when the slider is captured by the controller.

Oops, my bad. Lemme think about it.

I would like to skip this step of
pressing A and having that the moment
you focus a slider,

Have you actually tried giving the slider focus manually? When the cursor enters the widget, for example. You probably did, I’m unfamiliar with the intricacies of controllers in UMG :expressionless: It’s not about focus, it’s about capturing the input. Hm.

Thinking about how it’s done with mouse capture, I don’t think this can be achieved in pure BP. Not sure about slate either. Sorry.

Have you actually tried grating the slider focus manually?

It’s not about focus. It already has focus, it’s just that the system treats sliders in a different way for some reason.

I'm unfamiliar with the intricacies of controllers in UMG

Don’t worry. Thanks for the help :slight_smile:

Rats, I’m searching for a solution to this too

The solution here is simple. With your slider selected, look in the details panel for ‘Requires Controller Lock’ and turn this off. Now you can change the slider’s value without having to click to activate it.

3 Likes

This would be a good solution apart from those cases when you still need to navigate left or right from the said slider, and you cannot set custom rules for navigation in Blueprints.

The issue is actually in the fact that for some reason the first time you press A to select the slider, it is not treated as OnKeyDown. If you have access to the engine code, and put a breakpoint at the beginning of this FReply SSlider::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent) (line 233 of SSlider.cpp located in your \EPIC\UE_5.3\Engine\Source\Runtime\Slate\Private\Widgets\Input\SSlider.cpp), you will see it doesn’t get fired at all. It will, however, get fired if you try pressing anything on the controller while holding A.

What should ideally happen is in the code after this line:

if (FSlateApplication::Get().GetNavigationActionFromKey(InKeyEvent) == EUINavigationAction::Accept && bRequiresControllerLock)

If that results to true, you should be able to manipulate the slider. However, it will not result to true because of this : EUINavigationAction::Accept

I assume that maybe A on the controller is perceived as Accept. But unfortunately, since the OnKeyDown wasn’t triggered by it, and we’re holding it down to keep focus, any other button you press on the controller will result in exiting from that code prematurely.

That code works well with keyboard. If you try to navigate using your keyboard, press Enter once, it will enter into that part of the code, as Enter is treated as ::Accept by default (found it in NavigationConfig.cpp(\EPIC\UE_5.3\Engine\Source\Runtime\Slate\Private\Framework\Application\NavigationConfig.cpp), line 162, in the comments it says: ‘// By default, enter, space, and gamepad accept are all counted as accept’.
Then, you can manipulate the slider with your arrow keys. And after you have finished, press Enter again to exit from the manipulation mode.

Unfortunately, I have no idea how to go about this. Seems the real problem is the OnKeyDown.