Enhanced Input — complete C++ Character (UE 5.8)
Depth for unreal-enhanced-input: a self-contained third-person Character that adds a mapping
context and binds move/look/jump. Verified against the Enhanced Input documentation.
Header
// MyCharacter.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MyCharacter.generated.h"
class UInputMappingContext;
class UInputAction;
struct FInputActionValue;
UCLASS()
class MYGAME_API AMyCharacter : public ACharacter
{
GENERATED_BODY()
public:
AMyCharacter();
protected:
virtual void BeginPlay() override;
virtual void SetupPlayerInputComponent(UInputComponent* InputComponent) override;
// Assign these in the Blueprint subclass (IMC_/IA_ assets).
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputMappingContext> DefaultMappingContext;
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputAction> MoveAction;
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputAction> LookAction;
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputAction> JumpAction;
void Move(const FInputActionValue& Value);
void Look(const FInputActionValue& Value);
};Source
// MyCharacter.cpp
#include "MyCharacter.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "InputActionValue.h"
AMyCharacter::AMyCharacter()
{
// (camera/spring-arm setup omitted — see unreal-cpp-gameplay references)
}
void AMyCharacter::BeginPlay()
{
Super::BeginPlay();
if (APlayerController* PC = Cast<APlayerController>(GetController()))
if (ULocalPlayer* LP = PC->GetLocalPlayer())
if (UEnhancedInputLocalPlayerSubsystem* Subsystem =
LP->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* InputComponent)
{
Super::SetupPlayerInputComponent(InputComponent);
if (UEnhancedInputComponent* EIC = Cast<UEnhancedInputComponent>(InputComponent))
{
EIC->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyCharacter::Move);
EIC->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMyCharacter::Look);
EIC->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump);
EIC->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);
}
}
void AMyCharacter::Move(const FInputActionValue& Value)
{
const FVector2D Axis = Value.Get<FVector2D>();
if (Controller)
{
// Move relative to where the controller is facing (yaw only).
const FRotator Yaw(0, Controller->GetControlRotation().Yaw, 0);
AddMovementInput(FRotationMatrix(Yaw).GetUnitAxis(EAxis::X), Axis.Y);
AddMovementInput(FRotationMatrix(Yaw).GetUnitAxis(EAxis::Y), Axis.X);
}
}
void AMyCharacter::Look(const FInputActionValue& Value)
{
const FVector2D Axis = Value.Get<FVector2D>();
AddControllerYawInput(Axis.X);
AddControllerPitchInput(Axis.Y);
}Build.cs
PublicDependencyModuleNames.AddRange(new string[]
{
"Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput"
});Asset setup checklist (editor)
IA_Move— Value Type Axis2D;IA_Look— Axis2D;IA_Jump— Digital (bool).IMC_Defaultmappings:IA_Move: W (no modifier), S (Negate), and a Swizzle Input Axis Values on the up/down keys so vertical maps to Y; A (Negate), D for X.IA_Look: Mouse XY (add Negate on Y if inverted); gamepad right stick.IA_Jump: Space Bar / gamepad face button.
- In the Blueprint subclass of
AMyCharacter, assignDefaultMappingContextand the threeIA_assets.
Runtime rebinding note
Enhanced Input supports Player Mappable Key Settings on an Input Action plus the
UEnhancedInputUserSettings subsystem to remap and persist keys at runtime — the supported
path for a "rebind controls" menu in UE5. Mark the action's mapping as Player Mappable and
query/modify it through that subsystem rather than editing the IMC_ asset.