Navigation Config
The navigation config can be used to customize the keys used to navigate around elements in Unreal.
Customizing Navigation Keys
The engine comes with two example classes FNullNavigationConfig, and FTwinStickNavigationConfig which are basic examples of how to customize the default navigation keys
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}
};
}
bool FTwinStickNavigationConfig::IsAnalogHorizontalKey(const FKey& InKey) const
{
return InKey == EKeys::Gamepad_LeftX || InKey == EKeys::Gamepad_RightX;
}
bool FTwinStickNavigationConfig::IsAnalogVerticalKey(const FKey& InKey) const
{
return InKey == EKeys::Gamepad_LeftY || InKey == EKeys::Gamepad_RightY;
}
Example: Dynamically change keys to be used as navigation
Navigation keys can be updated at runtime to be handled as navigation or not via the NavigationConfig. Below is an example of a FDynamicNavigationConfig that matches Unreal's default navigation keys to start with, but can be updated to enable and disable more keys by calling FDynamicNavigationConfig::SetKeyWithDirection(...)
- .h
- .cpp
class FDynamicNavigationConfig : public FNavigationConfig
{
FDynamicNavigationConfig();
public:
// Sets the InKey to the given InEnabledDirection. If bIsEnabled = false, will set the InKey to be invalid and not handle navigation
static void SetKeyWithDirection(const ULocalPlayer\* InLocalPlayer, const FKey& InKey, bool bIsEnabled, EUINavigation InEnabledNavDirection);
/* Sets the given `InKey` to the given `InUINavigation`
* Example Usage:
* SetKeyDirection(EKeys::Gamepad_Dpad_Up, EUINavigation::Invalid) to make DPad up not be used for navigation
* SetKeyDirection(EKeys::Gamepad_Face_Up, EUINavigation::Up) to make Face Up (Y) to be used for navigating up
*/
void SetKeyDirection(const FKey& InKey, EUINavigation InUINavigation);
protected:
bool IsAnalogHorizontalKey(const FKey& InKey) const override;
bool IsAnalogVerticalKey(const FKey& InKey) const override;
};
#include "DynamicNavigationConfig.h"
FDynamicNavigationConfig::FDynamicNavigationConfig()
{
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 } };
}
void FDynamicNavigationConfig::SetKeyWithDirection(const ULocalPlayer* InLocalPlayer, const FKey& InKey, const bool bIsEnabled, const EUINavigation InEnabledNavDirection)
{
if (!FSlateApplication::IsInitialized())
{
return;
}
auto& SlateApp = FSlateApplication::Get();
const auto SlateUser = SlateApp.GetUser(InLocalPlayer->GetPlatformUserId());
// Try to get the config, may be invalid if not set before
auto NavigationConfig = SlateUser->GetUserNavigationConfig();
if (!NavigationConfig.IsValid())
{
NavigationConfig = MakeShared<FDynamicNavigationConfig>();
SlateUser->SetUserNavigationConfig(NavigationConfig);
}
// Update direction for the given key
if (const auto DynamicNavConfig = Cast<FDynamicNavigationConfig>(NavigationConfig.Get()))
{
DynamicNavConfig->SetKeyDirection(InKey, bIsEnabled ? InEnabledNavDirection : EUINavigation::Invalid);
}
}
void FDynamicNavigationConfig::SetKeyDirection(const FKey& InKey, EUINavigation InUINavigation)
{
KeyEventRules.FindOrAdd(InKey) = InUINavigation;
}
bool FDynamicNavigationConfig::IsAnalogHorizontalKey(const FKey& InKey) const
{
return InKey == EKeys::Gamepad_LeftX || InKey == EKeys::Gamepad_RightX;
}
bool FDynamicNavigationConfig::IsAnalogVerticalKey(const FKey& InKey) const
{
return InKey == EKeys::Gamepad_LeftY || InKey == EKeys::Gamepad_RightY;
}