Find and fix the bug in this ACharacter movement input code in Unreal Engine.
This ACharacter should move forward in the direction the player is looking, but it always slides along world +X no matter where the camera faces.
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* Input)
{
Super::SetupPlayerInputComponent(Input);
Input->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);
}
void AMyCharacter::MoveForward(float Value)
{
const FVector Direction(1.f, 0.f, 0.f);
AddMovementInput(Direction, Value);
}
Find and fix the bug.
The handler calls AddMovementInput with a world-axis vector that ignores the controller's yaw, so the character always moves along world X regardless of where it faces. Fix it by deriving the direction from the control rotation's forward vector.
- ✗Using a fixed world-axis vector instead of a direction relative to control rotation
- ✗Forgetting to zero the pitch/roll so the character isn't pushed into the ground
- ✗Confusing the Actor's rotation with the controller's control rotation
- →Why use the control rotation instead of the Actor's rotation for movement?
- →How would you add strafing (right/left) movement correctly?
Buggy code
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* Input)
{
Super::SetupPlayerInputComponent(Input);
Input->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);
}
void AMyCharacter::MoveForward(float Value)
{
// BUG: hard-coded world X axis
const FVector Direction(1.f, 0.f, 0.f);
AddMovementInput(Direction, Value);
}
Diagnosis
The character always moves along world +X, no matter where the camera faces. The cause is the Direction vector hard-coded as a world axis, ignoring the controller's yaw. AddMovementInput expects a world-space direction; it must be built from the control rotation (GetControlRotation()), not from a fixed axis.
It also matters to zero the pitch and roll: if pitch is kept, the forward vector tilts up or down and the character is dragged into the ground or the air.
Fix
void AMyCharacter::MoveForward(float Value)
{
if (Controller == nullptr || Value == 0.f)
{
return;
}
// Take only the yaw of the control rotation
const FRotator YawRotation(0.f, Controller->GetControlRotation().Yaw, 0.f);
// Forward vector flattened to the ground plane
const FVector Direction =
FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
Now the direction is derived from the controller's current yaw, so the character moves where the player is looking.