MiddleКодЧастоЕщё не отвечали
Как плавно поворачивать актёра к движущейся цели каждый кадр?
Внутри Tick актёра плавно поворачивайте его каждый кадр так, чтобы его ось forward смотрела на TargetActor, который может двигаться.
Ограничения:
не ставьте резко и не лерпите компоненты FRotator вручную.
- Постройте желаемый поворот из направления к цели (forward = ось X).
- Идите к нему независимо от FPS — передавайте
DeltaTimeв интерполяцию, - Безопасно выходите, когда цель совпадает с позицией самого актёра.
void AEnemy::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// ваш код здесь
}
Допишите реализацию.
Постройте желаемый поворот через FRotationMatrix::MakeFromX(Direction).Rotator() или (Target - Self).Rotation(), затем плавно идите к нему через FMath::RInterpTo(Current, Desired, DeltaTime, Speed) и примените SetActorRotation.
- ✗Резко ставить
SetActorRotationна поворот цели, полностью пропуская интерполяцию - ✗Забыть передать
DeltaTimeвRInterpTo, из-за чего скорость поворота зависит от FPS - ✗Линейно лерпить компоненты
FRotatorи поворачивать длинным путём после 180 градусов
- →Как ограничить поворот, чтобы актёр менял только yaw и никогда pitch?
- →Почему
RInterpToпредпочтительнее линейной интерполяции компонентFRotator?
Плавный поворот к цели
void AEnemy::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (!TargetActor)
return;
// Направление от себя к цели в мировом пространстве
const FVector Direction =
(TargetActor->GetActorLocation() - GetActorLocation()).GetSafeNormal();
if (Direction.IsNearlyZero())
return; // цель совпала с нашей позицией
// Желаемый поворот: ось X (forward) смотрит на цель
const FRotator DesiredRotation = Direction.Rotation();
const FRotator CurrentRotation = GetActorRotation();
// Плавная интерполяция, независимая от частоты кадров
const FRotator NewRotation = FMath::RInterpTo(
CurrentRotation, DesiredRotation, DeltaTime, RotationSpeed);
SetActorRotation(NewRotation);
}
Ключевые моменты:
Direction.Rotation()строитFRotator, у которого ось X (forward) направлена на цель.RInterpToполучаетDeltaTime, поэтому скорость поворота одинакова при любом FPS.RInterpToидёт по кратчайшему пути и не «перематывает» через 180°, в отличие от покомпонентногоLerp.
Чтобы поворачивать только по горизонтали (типично для персонажей), обнулите pitch и roll:
FRotator DesiredYawOnly = Direction.Rotation();
DesiredYawOnly.Pitch = 0.0f;
DesiredYawOnly.Roll = 0.0f;