I’m new at using the Unreal Engine, and it took me all this hacking to implement a rotation action that didn’t flip/pirouette crazily around the 0/360 crossover. Is there a much easier/simpler way I should have done this?
void APlayer::UnwindTargetYaw()
{
float CurrentYaw = GetControlRotation().Yaw;
if (FMath::Abs(TargetControllerYaw - CurrentYaw) > 180)
{
if (FMath::Abs(TargetControllerYaw + 360.0f - CurrentYaw) < 180)
{
TargetControllerYaw += 360.0f;
}
else if (FMath::Abs(TargetControllerYaw - 360.0f - CurrentYaw) < 180)
{
TargetControllerYaw -= 360.0f;
}
else
{
TargetControllerYaw = CurrentYaw < 180 ? CurrentYaw + 180 : CurrentYaw - 180;
}
}
}
void APlayer::Rotate(const FInputActionValue& Value)
{
// input is a Vector2D
const FVector2D LookAxisVector = Value.Get<FVector2D>();
if (Controller != nullptr)
{
// add yaw and pitch input to controller
TargetControllerYaw = TargetControllerYaw + LookAxisVector.X;
UnwindTargetYaw();
}
}
// Called every frame
void APlayer::Tick(const float DeltaTime)
{
Super::Tick(DeltaTime);
MaintainFloatingHeight(DeltaTime);
// Smooth boom arm length transition
SpringArm->TargetArmLength = FMath::FInterpTo(SpringArm->TargetArmLength, TargetBoomLength, DeltaTime,
BoomLengthInterpSpeed);
RecalculateCameraRotation();
// Smooth pitch adjustment
FRotator CurrentRotation = SpringArm->GetRelativeRotation();
CurrentRotation.Pitch = FMath::FInterpTo(CurrentRotation.Pitch, TargetBoomPitch, DeltaTime, BoomPitchInterpSpeed);
SpringArm->SetRelativeRotation(CurrentRotation);
UnwindTargetYaw();
float CurrentYaw = GetControlRotation().Yaw;
float NormalizedTargetYaw = TargetControllerYaw;
float NormalizedCurrentYaw = CurrentYaw;
if (NormalizedTargetYaw < 0)
{
NormalizedTargetYaw += 360;
if (NormalizedCurrentYaw < 180)
{
NormalizedCurrentYaw += 360;
}
}
float YawDelta = FMath::FInterpTo(NormalizedCurrentYaw, NormalizedTargetYaw, DeltaTime, RotateInterpSpeed) -
NormalizedCurrentYaw;
UE_LOG(LogTemp, Warning, TEXT("Current Yaw: %f, Target Yaw: %f, Yaw Delta: %f"), CurrentYaw, TargetControllerYaw,
YawDelta)
if (FMath::Abs(YawDelta) >= 0.01f)
{
AddControllerYawInput(YawDelta);
}
else
{
TargetControllerYaw = CurrentYaw;
}
}