Proper code to retrieve keyboard input from actor component

Hey guys,

I’m trying to use C++ code to say “if the player presses the “F” key on the keyboard, then perform some animation”. In the Project Settings, in the Engine Input category, I’ve made an action mapping called “WallClimbJumpUp2m” that is bound to the “F” key on the keyboard.

Then, I have a character blueprint on which I’ve added an “Actor Component” C++ script. I’m not sure if this is the right type of C++ script to use, or if it’s on the right object though? I’ve read several tutorials so far, but none of them seem to work so far unfortunately. Here is a picture of where I placed the C++ script in my character blueprint:

Here is the C++ code I’m using in the actor component script:

This is the header file:

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "AnimCodeManager1.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class LARGETERRAIN1_API UAnimCodeManager1 : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UAnimCodeManager1();

protected:
	// Called when the game starts
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent);

	//UFUNCTION()
	//void SetupInput();

	void WallClimbUp2m();

private:
	UPROPERTY()
		class UInputComponent* InputComponent;


		
	
};

And this is the CPP file:

#include "AnimCodeManager1.h"
#include "GrmaleAnimInstance1.h"


// Sets default values for this component's properties
UAnimCodeManager1::UAnimCodeManager1()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;
	
}


// Called when the game starts
void UAnimCodeManager1::BeginPlay()
{
	Super::BeginPlay();

}


// Called every frame
void UAnimCodeManager1::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);


}





// Called to bind functionality to input
void UAnimCodeManager1::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
	//SetupPlayerInputComponent(InputComponent);
	check(InputComponent);

	InputComponent->BindAction("WallClimbJumpUp2m", IE_Pressed, this, &UAnimCodeManager1::WallClimbUp2m);

}




//void UAnimCodeManager1::SetupInput()
//{
	//EnableInput(this)
	//check(InputComponent);
	//InputComponent->BindAction("WallClimbJumpUp2m", IE_Released, this, &UAnimCodeManager1::WallClimbUp2m);
//}




// Function that gets called when the "should jump up/wall climb 2m" button is pressed
void UAnimCodeManager1::WallClimbUp2m() 
{
	// No Mesh?
	USkeletalMeshComponent *Mesh = GetOwner()->FindComponentByClass<USkeletalMeshComponent>();

	if (!Mesh) return;

	// Reference the animation blueprint instance that gets spawned when the game starts
	UGrmaleAnimInstance1 * Animation =
		Cast<UGrmaleAnimInstance1>(Mesh->GetAnimInstance());

	// No Anim Instance Acquired?
	if (!Animation) return;

	// Set the variable desired in the animation blueprint
	Animation->shouldJumpUp2m = true;
}

I’m assuming, from what I’ve read, that the UAnimCodeManager1::SetupPlayerInputComponent function is supposed to run by itself (without having to call it from the BeginPlay function or elsewhere). But maybe that’s only if it’s a part of some other type of C++ script (i.e. the Character script or Player Controller) ? I’m just not sure though.

Thanks for any help.

Well, I finally got it working. I decided not to use an actor component to try to access the input. So, I deleted that class/script off of my character blueprint.

Then, I created a brand new custom “Player Controller” class in the content browser C++ folder. I set the “Player Controller” dropdown option in the Project Settings >> Maps and Modes to be this new custom player controller I created. From there, I was able to use one of the online tutorials’ code snippets to work.

Using a function like this, called from the BeginPlay() function of the custom player controller:

void ACustomPlayerController1::SetupInput()
{
	EnableInput(this);
	check(InputComponent);
	InputComponent->BindAction("WallClimbJumpUp2m", IE_Released, this, &ACustomPlayerController1::WallClimbUp2m);
}

At least it works now :slight_smile: