Input is overridden by navigation input in Common UI. How to override?

Hey all,

I am trying to retrieve an input action that is binded on an input that is normally also used for navigation: E.g. thumbstick left left / left right, gamepad left/right etc.

When I change the input to anything else e.g. face button top, the button is being triggered (clicked). But when I assign it to something that is used for navigation, it gets consumed and does not trigger the bound button.

I did find a workaround. For anyone that is searching for it, basically it is forcing the listen to the input and execute a custom event in the widget itself.

However, I would like to not use this workaround for cleanness. If anyone has an idea, please feel free to reach out.

Thank you in advance and with kind regards,

Eric

1 Like

Hey, as I’m facing the same problem, I wanted to thank you for your workaround.

And while I was implementing it, I also found another way:
In my widget “container” (for me it’s an horizontal box), I saw you can bind custom functions to respond to navigation input:

image

I’m not sure that’s what you are looking for, or if it’s “CommonUI-friendly”, but just wanted to mention it.

Thanks! Will try if this solves the automatic listen. For now my workaround seems very stable. I have found multiple of these things in Common UI. Probably will do a tutorial series on it.

The way I managed to work around this issue is to create a subclass of FNavigationConfig and to set it using FSlateApplication::Get().SetNavigationConfig(NavigationConfig);.
In my subclass, I overrode some methods such as virtual EUINavigation GetNavigationDirectionFromKey(const FKeyEvent& InKeyEvent) const override; that returns EUINavigation::Invalid when I disabled navigation.
You can also define your “mappings” for instance, the default is:

FNavigationConfig::FNavigationConfig()
	: bTabNavigation(true)
	, bKeyNavigation(true)
	, bAnalogNavigation(true)
	, bIgnoreModifiersForNavigationActions(true)
	, AnalogNavigationHorizontalThreshold(0.50f)
	, AnalogNavigationVerticalThreshold(0.50f)
{
	AnalogHorizontalKey = EKeys::Gamepad_LeftX;
	AnalogVerticalKey = EKeys::Gamepad_LeftY;

	KeyEventRules.Emplace(EKeys::Left, EUINavigation::Left);
	KeyEventRules.Emplace(EKeys::Gamepad_DPad_Left, EUINavigation::Left);

	KeyEventRules.Emplace(EKeys::Right, EUINavigation::Right);
	KeyEventRules.Emplace(EKeys::Gamepad_DPad_Right, EUINavigation::Right);

	KeyEventRules.Emplace(EKeys::Up, EUINavigation::Up);
	KeyEventRules.Emplace(EKeys::Gamepad_DPad_Up, EUINavigation::Up);

	KeyEventRules.Emplace(EKeys::Down, EUINavigation::Down);
	KeyEventRules.Emplace(EKeys::Gamepad_DPad_Down, EUINavigation::Down);

	// By default, enter, space, and gamepad accept are all counted as accept
	KeyActionRules.Emplace(EKeys::Enter, EUINavigationAction::Accept);
	KeyActionRules.Emplace(EKeys::SpaceBar, EUINavigationAction::Accept);
	KeyActionRules.Emplace(EKeys::Virtual_Accept, EUINavigationAction::Accept);

	// By default, escape and gamepad back count as leaving current scope
	KeyActionRules.Emplace(EKeys::Escape, EUINavigationAction::Back);
	KeyActionRules.Emplace(EKeys::Virtual_Back, EUINavigationAction::Back);
}

But the engine also offers an alternate nav config with a subclass defining its own rules (and a good place to learn more about the Navigation config):

FTwinStickNavigationConfig::FTwinStickNavigationConfig()
{
	bTabNavigation = false;

	KeyEventRules =
	{
		{EKeys::Gamepad_DPad_Left, EUINavigation::Left},
		{EKeys::Gamepad_DPad_Right, EUINavigation::Right},
		{EKeys::Gamepad_DPad_Up, EUINavigation::Up},
		{EKeys::Gamepad_DPad_Down, EUINavigation::Down}
	};
}

You can simply rebind the navigation input in this way, without creating new subclasses. Don’t forget to connect the Slate module and include Slate.h.

	TSharedRef<FNavigationConfig> InNavigationConfig = FSlateApplication::Get().GetNavigationConfig();

	InNavigationConfig.Get().AnalogHorizontalKey = EKeys::Gamepad_RightX;
	InNavigationConfig.Get().AnalogVerticalKey = EKeys::Gamepad_RightY;

	FSlateApplication::Get().SetNavigationConfig(InNavigationConfig);
1 Like

Where am I supposed to write this code ? I’m really new to c++ and have no idea how to override these ui navigation it’s so frustrating

(post deleted by author)

(post deleted by author)

One thing you could do is run a branch from your input in your character and then have the beginning of what your working on say hey this needs to stop now so when i activate this widget i need to also set a Boolean which will make it so your input has no effect but you can still effect your widget, you may also want to get the focus of the thing your doing initially when opening your widget as well.
Hope it helps.