Using FIrst Person Controls in a Third Person Shooter with bOrientRotationToMovement causes unexpected backwards walking

I know that in FPS projects, the character moves forward relative to the actor’s forward vector. In Third Person Shooters, it moves relative to the direction the camera points, and the character rotates towards the direction at the same time (bOrientRotationToMovement).

If I simply attempt to plug in FPS controls in a Third Person Shooter game, I’d expect the character simply behaves independently from the camera, and left/right movement simply rotates the actor in place and front-back movement allows the actor to progress. That’s all expected. But when the backwards key is pressed, instead of simply moving backwards, the actor seems to move in a global direction and glitches as it moves.

The actor I used was a CPP implementation, with MoveRight & MoveForward functions below. Check the video for a demonstration on the glitch.

// FPS controls
void AUserCharacter::MoveRight(float Val) {
  if (Val != 0.f) {
    AddMovementInput(GetActorRightVector(), Val);
  }
}

void AUserCharacter::MoveForward(float Val) {
  if (Val != 0.f) {
    AddMovementInput(GetActorForwardVector(), Val);
  }
}

The Constructor:

AUserCharacter::AUserCharacter() {
  PrimaryActorTick.bCanEverTick = true;
  CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
  CameraBoom->SetupAttachment(RootComponent);
  CameraBoom->TargetArmLength = 300.f;
  CameraBoom->bUsePawnControlRotation = true; // allows camera to not always lock on character

  FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
  FollowCamera->SetupAttachment(CameraBoom);
  FollowCamera->bUsePawnControlRotation = false; // camera's rotation relative to cameraboom 

  GetMesh()->SetRelativeLocation({0,0,-170./2});
  GetMesh()->SetRelativeRotation({0, -90, -0}); // turn the character left/right, z

  constexpr bool bRotate = false;
  bUseControllerRotationPitch = bRotate;
  bUseControllerRotationYaw = bRotate;
  bUseControllerRotationRoll = bRotate;

  GetCharacterMovement()->bOrientRotationToMovement = !bRotate;
  GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.f, 0.0f);

  
}
// TPS Controls (Not used)
void AUserCharacter::MoveRight(float Val) {
  const FRotator Rotation = Controller->GetControlRotation();
  const FRotator YawRotation(0.0f, Rotation.Yaw, 0.0f);
  
  const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
  AddMovementInput(RightDirection, Val);
  
}

void AUserCharacter::MoveForward(float Val) {
  if (Controller != nullptr && (Val != 0.0f)) {
    const FRotator Rotation = Controller->GetControlRotation();
    const FRotator YawRotation(0.0f, Rotation.Yaw, 0.0f);
  
    const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
    AddMovementInput(ForwardDirection, Val);
  }
}

Video of character behavior: (30 second video)
2022-04-24 01-15-21.mkv (5.3 MB)

Anybody who can explain what this scenario is about?

You are using MoveRight and MoveForward which are project input settings that can be changed in Project Settings > Input and are mapped to specific keys/controllers into InputActions and InputAxis.

The two projects must be using different input mappings and thus you are receiving the mixture of the two if you haven’t updated the inputs.

I pulled out the input mappings of a default FPS and Third Person Shooter project. Both seems to be identical.

Also I used the same project to test the 2 variations of the MoveRight and MoveForward functions, which have the same input bindings.