KeyBindings

KeyBindings

#Overview

name: KeyBindings

The value of this variable can be defined or overridden in .ini config files. 9 .ini config files referencing this setting variable.

It is referenced in 17 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of KeyBindings is to store and manage input key bindings for various components and systems within Unreal Engine 5. It is primarily used for handling user input and mapping keys to specific actions or functions in the game or editor.

KeyBindings is utilized by several Unreal Engine subsystems and modules, including:

  1. The Avalanche Media plugin
  2. The Gameplay Debugger
  3. The UnrealEd module (Editor key bindings)
  4. The Engine’s input system

The value of this variable is typically set in different ways depending on the context:

  1. In the Avalanche Media plugin, it’s set as a UPROPERTY in the UAvaRundownMacroCollection class.
  2. In the UnrealEd module, it’s set as a config UPROPERTY in the UUnrealEdKeyBindings class.
  3. In the Engine’s input system, it’s populated through various binding functions like BindKey().

KeyBindings often interacts with other variables and systems, such as:

  1. InputComponent: KeyBindings is a member of the UInputComponent class.
  2. InputChord: Used to represent key combinations.
  3. Various delegate types for handling input events.

Developers should be aware of the following when using KeyBindings:

  1. Key bindings can be overridden, so care should be taken when managing multiple bindings for the same key or action.
  2. The order of key bindings can be important, especially when dealing with parent-child relationships or priority.

Best practices when using KeyBindings include:

  1. Properly cleaning up and resetting bindings when no longer needed.
  2. Using appropriate scoping and organization to avoid conflicts between different systems or game modes.
  3. Considering performance implications when iterating through large numbers of key bindings.
  4. Utilizing the provided binding functions (e.g., BindKey()) instead of manually manipulating the KeyBindings array when possible.
  5. Being mindful of the context in which KeyBindings is being used (editor, runtime, specific plugin) to ensure proper functionality.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEditorKeyBindings.ini:3, section: [/Script/UnrealEd.UnrealEdKeyBindings]

Location: <Workspace>/Engine/Config/BaseEditorKeyBindings.ini:4, section: [/Script/UnrealEd.UnrealEdKeyBindings]

Location: <Workspace>/Engine/Config/BaseEditorKeyBindings.ini:5, section: [/Script/UnrealEd.UnrealEdKeyBindings]

Location: <Workspace>/Engine/Config/BaseEditorKeyBindings.ini:6, section: [/Script/UnrealEd.UnrealEdKeyBindings]

Location: <Workspace>/Engine/Config/BaseEditorKeyBindings.ini:7, section: [/Script/UnrealEd.UnrealEdKeyBindings]

Location: <Workspace>/Engine/Config/BaseEditorKeyBindings.ini:8, section: [/Script/UnrealEd.UnrealEdKeyBindings]

Location: <Workspace>/Engine/Config/BaseEditorKeyBindings.ini:9, section: [/Script/UnrealEd.UnrealEdKeyBindings]

Location: <Workspace>/Engine/Config/BaseEditorKeyBindings.ini:10, section: [/Script/UnrealEd.UnrealEdKeyBindings]

Location: <Workspace>/Engine/Config/BaseEditorKeyBindings.ini:11, section: [/Script/UnrealEd.UnrealEdKeyBindings]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Plugins/Experimental/Avalanche/Source/AvalancheMedia/Private/Rundown/AvaRundownMacroCollection.cpp:4

Scope (from outer to inner):

file
function     bool UAvaRundownMacroCollection::HasBindingFor

Source code excerpt:

bool UAvaRundownMacroCollection::HasBindingFor(const FInputChord& InInputChord) const
{
	for (const FAvaRundownMacroKeyBinding& KeyBinding : KeyBindings)
	{
		if (KeyBinding.InputChord == InInputChord)
		{
			return true;
		}
	}

#Loc: <Workspace>/Engine/Plugins/Experimental/Avalanche/Source/AvalancheMedia/Private/Rundown/AvaRundownMacroCollection.cpp:17

Scope (from outer to inner):

file
function     int32 UAvaRundownMacroCollection::ForEachBinding

Source code excerpt:

{
	int32 NumBindings = 0;
	for (const FAvaRundownMacroKeyBinding& KeyBinding : KeyBindings)
	{
		if (KeyBinding.InputChord == InInputChord)
		{
			if (InCallback(KeyBinding))
			{
				++NumBindings;

#Loc: <Workspace>/Engine/Plugins/Experimental/Avalanche/Source/AvalancheMedia/Private/Rundown/AvaRundownMacroCollection.cpp:33

Scope (from outer to inner):

file
function     int32 UAvaRundownMacroCollection::ForEachCommand

Source code excerpt:

{
	int32 NumCommands = 0;
	for (const FAvaRundownMacroKeyBinding& KeyBinding : KeyBindings)
	{
		if (KeyBinding.InputChord == InInputChord)
		{
			for (const FAvaRundownMacroCommand& Command : KeyBinding.Commands)
			{
				if (InCallback(Command))

#Loc: <Workspace>/Engine/Plugins/Experimental/Avalanche/Source/AvalancheMedia/Public/Rundown/AvaRundownMacroCollection.h:56

Scope (from outer to inner):

file
class        class UAvaRundownMacroCollection : public UObject

Source code excerpt:

protected:
	UPROPERTY(EditAnywhere, Category="Marcos")
	TArray<FAvaRundownMacroKeyBinding> KeyBindings;
};

#Loc: <Workspace>/Engine/Source/Editor/GameplayDebugger/Private/GameplayDebuggerEdMode.cpp:84

Scope (from outer to inner):

file
function     bool FGameplayDebuggerEdMode::InputKey

Source code excerpt:


			// go over all bound actions
			const int32 NumBindings = DataPtr->InputComponent->KeyBindings.Num();
			for (int32 Idx = 0; Idx < NumBindings; Idx++)
			{
				const FInputKeyBinding& KeyBinding = DataPtr->InputComponent->KeyBindings[Idx];
				if (KeyBinding.KeyEvent == InEvent && KeyBinding.Chord == ActiveChord && KeyBinding.KeyDelegate.IsBound())
				{
					KeyBinding.KeyDelegate.Execute(InKey);
				}
			}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Preferences/UnrealEdKeyBindings.h:47

Scope (from outer to inner):

file
class        class UUnrealEdKeyBindings : public UObject

Source code excerpt:

	/** Array of keybindings */
	UPROPERTY(config)
	TArray<struct FEditorKeyBinding> KeyBindings;

};

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdEngine.cpp:1276

Scope (from outer to inner):

file
function     FString UUnrealEdOptions::GetExecCommand

Source code excerpt:

FString UUnrealEdOptions::GetExecCommand(FKey Key, bool bAltDown, bool bCtrlDown, bool bShiftDown, FName EditorSet)
{
	TArray<FEditorKeyBinding> &KeyBindings = EditorKeyBindings->KeyBindings;
	FString Result;

	for(int32 BindingIdx=0; BindingIdx<KeyBindings.Num(); BindingIdx++)
	{
		FEditorKeyBinding &Binding = KeyBindings[BindingIdx];
		int32* CommandIdx = CommandMap.Find(Binding.CommandName);

		if(CommandIdx && EditorCommands.IsValidIndex(*CommandIdx))
		{
			FEditorCommand &Cmd = EditorCommands[*CommandIdx];

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Components/InputComponent.h:730

Scope (from outer to inner):

file
class        class UInputComponent : public UActorComponent

Source code excerpt:


	/** The collection of key bindings. */
	TArray<FInputKeyBinding> KeyBindings;

	/** The collection of touch bindings. */
	TArray<FInputTouchBinding> TouchBindings;

	/** The collection of axis bindings. */
	TArray<FInputAxisBinding> AxisBindings;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Components/InputComponent.h:997

Scope (from outer to inner):

file
class        class UInputComponent : public UActorComponent
function     FInputKeyBinding& BindKey

Source code excerpt:

		FInputKeyBinding KB(Chord, KeyEvent);
		KB.KeyDelegate.BindDelegate(Object, Func);
		KeyBindings.Emplace(MoveTemp(KB));
		return KeyBindings.Last();
	}

	/**
	 * Binds a key event to a delegate function.
	 * Returned reference is only guaranteed to be valid until another input key is bound.
	 */

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Components/InputComponent.h:1020

Scope (from outer to inner):

file
class        class UInputComponent : public UActorComponent
function     FInputKeyBinding& BindKey

Source code excerpt:

		FInputKeyBinding KB(FInputChord(Key, false, false, false, false), KeyEvent);
		KB.KeyDelegate.BindDelegate(Object, Func);
		KeyBindings.Emplace(MoveTemp(KB));
		return KeyBindings.Last();
	}

	/**
	 * Binds this input component to touch events.
	 * Returned reference is only guaranteed to be valid until another touch event is bound.
	 */

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/InputComponent.cpp:228

Scope (from outer to inner):

file
function     bool UInputComponent::HasBindings

Source code excerpt:

			(AxisBindings.Num() > 0) ||
			(AxisKeyBindings.Num() > 0) ||
			(KeyBindings.Num() > 0) ||
			(TouchBindings.Num() > 0) ||
			(GestureBindings.Num() > 0) ||
			(VectorAxisBindings.Num() > 0));
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/InputKeyDelegateBinding.cpp:25

Scope (from outer to inner):

file
function     void UInputKeyDelegateBinding::BindToInputComponent

Source code excerpt:

		if (Binding.bOverrideParentBinding)
		{
			for (int32 ExistingIndex = InputComponent->KeyBindings.Num() - 1; ExistingIndex >= 0; --ExistingIndex)
			{
				const FInputKeyBinding& ExistingBind = InputComponent->KeyBindings[ExistingIndex];
				if (ExistingBind.Chord == KB.Chord && ExistingBind.KeyEvent == KB.KeyEvent)
				{
					InputComponent->KeyBindings.RemoveAt(ExistingIndex);
				}
			}
		}

		// To avoid binds in the same layer being removed by the parent override temporarily put them in this array and add later
		BindsToAdd.Add(KB);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/InputKeyDelegateBinding.cpp:41

Scope (from outer to inner):

file
function     void UInputKeyDelegateBinding::BindToInputComponent

Source code excerpt:

	for (int32 Index=0; Index < BindsToAdd.Num(); ++Index)
	{
		InputComponent->KeyBindings.Add(BindsToAdd[Index]);
	}
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/UserInterface/PlayerInput.cpp:1310

Scope (from outer to inner):

file
function     void UPlayerInput::EvaluateInputDelegates

Source code excerpt:

			PotentialActions.Reset();

			for (const FInputKeyBinding& KeyBinding : IC->KeyBindings)
			{
				GetChordForKey(KeyBinding, bGamePaused, FoundChords, KeysToConsume);
			}

			FoundChords.Sort(FDelegateDispatchDetailsSorter());

#Loc: <Workspace>/Engine/Source/Runtime/GameplayDebugger/Private/GameplayDebuggerLocalController.cpp:534

Scope (from outer to inner):

file
function     void UGameplayDebuggerLocalController::BindInput

Source code excerpt:

					InputBinding.KeyDelegate.GetDelegateForManualSet().BindUObject(this, &UGameplayDebuggerLocalController::OnCategoryBindingEvent, Idx, HandlerIdx);

					InputComponent.KeyBindings.Add(InputBinding);
					NewBindings.Add(HandlerData.KeyName);
				}
			}
		}

		const int32 NumExtentions = bSimulateMode ? 0 : CachedReplicator->GetNumExtensions();

#Loc: <Workspace>/Engine/Source/Runtime/GameplayDebugger/Private/GameplayDebuggerLocalController.cpp:555

Scope (from outer to inner):

file
function     void UGameplayDebuggerLocalController::BindInput

Source code excerpt:

					InputBinding.KeyDelegate.GetDelegateForManualSet().BindUObject(this, &UGameplayDebuggerLocalController::OnExtensionBindingEvent, Idx, HandlerIdx);

					InputComponent.KeyBindings.Add(InputBinding);
					NewBindings.Add(HandlerData.KeyName);
				}
			}
		}
	}

#Loc: <Workspace>/Engine/Source/Runtime/GameplayDebugger/Private/GameplayDebuggerPlayerManager.cpp:234

Scope (from outer to inner):

file
function     void AGameplayDebuggerPlayerManager::RefreshInputBindings

Source code excerpt:

			TestData.InputComponent->ClearActionBindings();
			TestData.InputComponent->ClearBindingValues();
			TestData.InputComponent->KeyBindings.Empty();

			TestData.Controller->BindInput(*TestData.InputComponent);
		}
	}
#endif // WITH_GAMEPLAY_DEBUGGER_MENU
}