How can I bind Enhanced Input actions to functions in PlayerController using C++?

Edited for most recent progress, or lack thereof.

All of the tutorials I’ve seen involve using SetupPlayerInputComponent in a Pawn or Character. I would like to bind actions to functions in my PlayerController that are independent of the Pawn. This is what I have so far:

#include "EnhancedInputPlayerController.h"
#include "EnhancedInputSubsystems.h"
#include "InputMappingContext.h"
#include "EnhancedInputComponent.h"
#include "GameFramework/InputSettings.h"
#include "Engine/LocalPlayer.h"

AEnhancedInputPlayerController::AEnhancedInputPlayerController()
{
	// /Script/EnhancedInput.InputMappingContext'/Game/HowToInput/HowToInputMapping.HowToInputMapping'
	static ConstructorHelpers::FObjectFinder<UInputMappingContext> EnhancedInputObjectFinder(TEXT("/Game/HowToInput/HowToInputMapping.HowToInputMapping"));
	InputMappingContext = EnhancedInputObjectFinder.Object;
}

void AEnhancedInputPlayerController::BeginPlay()
{
	if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
	{	
		check(InputMappingContext);
		Subsystem->AddMappingContext(InputMappingContext, 0);

		static const FName InputComponentName(TEXT("InputComponent0"));
		UInputComponent* PlayerInputComponent = NewObject<UInputComponent>(this, UInputSettings::GetDefaultInputComponentClass(), InputComponentName);
		SetupPlayerInputComponent(PlayerInputComponent);
	}
}

void AEnhancedInputPlayerController::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	UEnhancedInputComponent* Input = Cast<UEnhancedInputComponent>(PlayerInputComponent);
	
	FInputActionBinding AB(TEXT("IA_TestMessage"), EInputEvent::IE_Pressed);
	AB.ActionDelegate.BindDelegate(this, &AEnhancedInputPlayerController::TestMessage);
	Input->AddActionBinding(MoveTemp(AB));
}

void AEnhancedInputPlayerController::TestMessage()
{
	GEngine->AddOnScreenDebugMessage(-1, 7.0f, FColor::Yellow, TEXT("TEST MESSAGE!"));
}

I feel like I must be making this more complicated than necessary, and it’s not working. I just want to listen for an input and make it do something in my PlayerController. When I use the console command “ShowDebug EnhancedInput” I can see that my action IA_TestMessage is firing. It just isn’t bound to my TestMessage function. I’m not seeing “TEST MESSAGE!” appear when I press the button.

So how do I bind an enhanced input action to a function in the PlayerController? It seems like this should be an easy task, but I’m just not getting it.

Bumping. Updated code. Still not working.

Fixed it. This is all I needed to do. No need to do anything in the constructor or in BeginPlay.

void AEnhancedInputPlayerController::SetupInputComponent()
{
	Super::SetupInputComponent();

	if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
	{
		class UInputMappingContext* InputMapping = Cast<UInputMappingContext>(StaticLoadObject(UInputMappingContext::StaticClass(), this, TEXT("/Game/HowToInput/HowToInputMapping.HowToInputMapping")));
		Subsystem->AddMappingContext(InputMapping, 0);
	}
	if (UEnhancedInputComponent* Input = CastChecked<UEnhancedInputComponent>(InputComponent))
	{
		class UInputAction* TestMessageAction = Cast<UInputAction>(StaticLoadObject(UInputAction::StaticClass(), this, TEXT("/Script/EnhancedInput.InputAction'/Game/HowToInput/IA_TestMessage.IA_TestMessage'")));
		Input->BindAction(TestMessageAction, ETriggerEvent::Triggered, this, &AEnhancedInputPlayerController::TestMessage);
	}
}

void AEnhancedInputPlayerController::TestMessage()
{
	GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Yellow, TEXT("PlayerController TEST MESSAGE!"));
}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.