After having added some custom input logic to the third person C++ project I read that a best practice is to put all input logic in a custom Player Controller class instead of directly in the Pawn. I am endeavoring to do this.
In my game mode class constructor I’ve added:
PlayerControllerClass = APTPlayerController::StaticClass();
This will then trigger my APTPlayerController::SetupInputComponent() to be called. This makes me think I’m on the right path. The contents of that function is as follows:
void APTPlayerController::SetupInputComponent()
{
APlayerController::SetupInputComponent();
// Perhaps this is where I've gone wrong? This is the only way I've found
// to lookup the pawn class so that this player controller can possess it.
for(TObjectIterator<APewterStrongCharacter> Itr; Itr; ++Itr)
{
if(Itr->IsA(APewterStrongCharacter::StaticClass()))
{
Possess(*Itr);
break;
}
}
ACharacter* pCharacter = GetCharacter();
if(pCharacter)
{
InputComponent->BindAction("Jump", IE_Pressed, pCharacter, &ACharacter::Jump);
InputComponent->BindAction("Jump", IE_Released, pCharacter, &ACharacter::StopJumping);
InputComponent->BindAxis("MoveForward", this, &APTPlayerController::MoveForward);
InputComponent->BindAxis("MoveRight", this, &APTPlayerController::MoveRight);
// We have 2 versions of the rotation bindings to handle different kinds of devices differently
// "turn" handles devices that provide an absolute delta, such as a mouse.
// "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick
InputComponent->BindAxis("Turn", pCharacter, &APawn::AddControllerYawInput);
InputComponent->BindAxis("TurnRate", this, &APTPlayerController::TurnAtRate);
InputComponent->BindAxis("LookUp", pCharacter, &APawn::AddControllerPitchInput);
InputComponent->BindAxis("LookUpRate", this, &APTPlayerController::LookUpAtRate);
InputComponent->BindAxis("CameraZoom", this, &APTPlayerController::CameraZoom);
InputComponent->BindAxis("CameraZoomController", this, &APTPlayerController::CameraZoomController);
// handle touch devices
InputComponent->BindTouch(IE_Pressed, this, &APTPlayerController::TouchStarted);
InputComponent->BindTouch(IE_Released, this, &APTPlayerController::TouchStopped);
}
}
In my custom player controller class I copy over all of the input logic from the ThirdPersonCharacter class. I then comment out the corresponding input logic in the ThirdPersonCharacter class. And lastly in the ThirdPersonCharacter blueprint this is actually spawned on the map, I change “AI Controller Class” from the default “PlayerController” to my custom “PTPlayerController”.
Even though my SetupInputComponent is called, the pawn seems to be possess correctly, the player controller has a character from GetCharacter() class, none of my input callbacks are hit when I press buttons during testing.
And a secondary but related mystery is I seem to be unable to add a constructor for my custom Player Controller class. I need it to initialize some state variables but any arrangement I try results in “already defined” errors from the compiler.