I made a custom player controller, where I disabled “show mouse cursor”, click events, mouse over events, generally all mouse input options.
I made UMG Huds in which I can navigate just by keyboard.
But when I click left mouse button whenever the umg is active, it loses keyboard focus and therefore it’s not responsive. I have to close this umg and open it again to navigate.
So how can I completely disable mouse input in my game? Even when I do recommended steps, it’s still present and disrupts my design.
my work around has been to check if all the buttons have user focus (making them into an array and then checking if each one has focus, and if none have any focus set it to the correct button) but this workaround takes long to implement on complex menu systems… seriously there has to be a better way
are you doing this for single player or local multiplayer, the reason i ask is if you want it for the local multiplayer the logic only needs to follow the 1st players buttons, becausr if he clicks and the focus is lost everyones fpcus is also lost so just reset everyones buttons to their default focus if player 1 loses focus (that way you only make an array of p1’s buttons…)
UpdateFocusVersion() has been renamed to IncrementFocusVersion()
IncrementFocusVersion() is now a protected function (only accessible from within the slate module) so it can’t be called from within custom user widgets.
I got around this by implementing NativeOnFocusChanging() in my custom button-containing user widget and calling SetFocus() on the button when (InFocusEvent.GetCause() == EFocusCause::Mouse). This will ensure that the focused button doesn’t lose focus when clicking elsewhere on the screen.
In regards to focus being lost when clicking, Epic should really make this into a configurable project setting so that people don’t have to go through the extra legwork to achieve the desired behavior. Looking at other threads, most people seem to be implementing really ugly hacks to get this working correctly.
In my specific instance I went with the following solution:
BaseUserWidgetFocusHacked.h:
UCLASS()
class EXAMPLE_API UBaseUserWidgetFocusHacked : public UUserWidget
{
GENERATED_BODY()
protected:
#if PLATFORM_DESKTOP || WITH_EDITOR
// This is only relevant on platforms with mouse support
virtual void NativeOnFocusChanging(const FWeakWidgetPath& PreviousFocusPath, const FWidgetPath& NewWidgetPath, const FFocusEvent& InFocusEvent) override;
#endif
};
BaseUserWidgetFocusHacked.cpp:
#if PLATFORM_DESKTOP || WITH_EDITOR
// This is only relevant on platforms with mouse support
void UBaseUserWidgetFocusHacked::NativeOnFocusChanging(const FWeakWidgetPath& PreviousFocusPath, const FWidgetPath& NewWidgetPath, const FFocusEvent& InFocusEvent)
{
if (PreviousFocusPath.IsValid() && NewWidgetPath.IsValid())
{
if (InFocusEvent.GetCause() == EFocusCause::Mouse && PreviousFocusPath.GetLastWidget() == TakeWidget() && NewWidgetPath.GetLastWidget()->GetType() != FName("UBaseUserWidgetFocusHacked"))
{
SetFocus();
return;
}
}
Super::NativeOnFocusChanging(PreviousFocusPath, NewWidgetPath, InFocusEvent);
}
#endif
I had already setup every single button in the game to subclass a specific UserWidget blueprint, so all I had to do was to change that blueprint to subclass this class.
Basically all it does is detect whether or not the mouse-driven focus change would switch from a widget of this type to any other kind of widget. Since all my user focusable widgets subclass this class this works just fine.
Much appreciated these posts! Also using 4.25 and ran into the same issue. First had an ugly hack where I had an invisible element covering the whole background and would refocus a button when clicked. This is really annoying to maintain on every UI page though and always focuses the same button rather than the most recently selected.
Some notes on my approach, which may help others:
The way I have my UI set up the GetLastWidget()->GetType() would always return the class “SViewPort” when clicking outside any UI element, so I just check for that instead. Probably because I set every element visibility without interaction to “not hit testable”. Reparent all widgets which have clickable elements in them to the new subclass and you are good to go. Your mileage may vary though.
If you get any unresolved symbols error when building after adding the NativeOnFocusChanging override (like I had), make sure you enabled Slate and SlateCore in your build.cs file.
I think its still relevant for many developers I found a solution and verified that it works in production. Hopes it will save a lot of time for somebody