Найдите и исправьте баг в этом коде ввода движения ACharacter в Unreal Engine.
Этот ACharacter должен двигаться вперёд туда, куда смотрит игрок, но он всегда скользит вдоль мировой +X независимо от направления камеры.
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);
}
Найдите и исправьте ошибку.
Обработчик вызывает AddMovementInput с вектором мировой оси, игнорирующим yaw контроллера, поэтому персонаж всегда движется вдоль мировой X независимо от направления взгляда. Исправление — выводить направление из forward-вектора управляющего поворота.
- ✗Использовать фиксированный вектор мировой оси вместо направления относительно поворота управления
- ✗Забывать обнулять pitch/roll, чтобы персонажа не вдавливало в землю
- ✗Путать поворот Actor с управляющим поворотом контроллера
- →Почему для движения использовать управляющий поворот, а не поворот Actor?
- →Как бы вы корректно добавили движение вбок (вправо/влево)?
Багованный код
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* Input)
{
Super::SetupPlayerInputComponent(Input);
Input->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);
}
void AMyCharacter::MoveForward(float Value)
{
// БАГ: жёстко зашитая мировая ось X
const FVector Direction(1.f, 0.f, 0.f);
AddMovementInput(Direction, Value);
}
Диагностика
Персонаж всегда движется вдоль мировой оси +X, куда бы ни смотрела камера. Причина — вектор Direction зашит как мировая ось и не учитывает yaw контроллера. AddMovementInput ожидает направление в мировом пространстве; нужно построить его из управляющего поворота (GetControlRotation()), а не из камеры персонажа.
Также важно обнулить pitch и roll: если оставить pitch, forward-вектор будет наклонён вверх или вниз, и персонажа будет тянуть в землю или в воздух.
Исправление
void AMyCharacter::MoveForward(float Value)
{
if (Controller == nullptr || Value == 0.f)
{
return;
}
// Берём только yaw управляющего поворота
const FRotator YawRotation(0.f, Controller->GetControlRotation().Yaw, 0.f);
// Forward-вектор в плоскости земли
const FVector Direction =
FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
Теперь направление выводится из текущего yaw контроллера, поэтому персонаж движется туда, куда смотрит игрок.