Ok, so I am trying to make expanded code for the Mover component that has 4 UPROPERTYS(EditAnywhere) which are: LocationOffSet, TimeToMove, RotatorOffSet, TimeToRotate. Now, the location portion works like a charm, and I had no issues, but the rotation portion has been screwing me for days. I have tried just using regular Rotators and RInterpConstantTo which works like a charm, UNLESS the start rotation + RotationOffSet > 90 degrees because at 90 degrees pitch, I get good ol’ Gimbal Lock. So, I then converted my rotators to Quaternions. This works like a charm, except the timetorotate doesn’t work correctly. It starts off correct, but the closer it gets to it’s target, the more it slows down until the final degree takes several minutes to complete when the whole rotation is supposed to take whatever seconds = TimeToRotate.
The issue is Lerp and Slerp with deltatime does not work the same as RInterpConstantTo or VInterpConstantTo. Can someone please help me with this, as I even tried asking every coding A.I. there was, and they either spit my code back at me, or just plain wrong code. I am only including the portion of code related to Rotation and everything works fine, except the rotation completing in the TimeToRotate specification. Thanks for your time! Code:
void UMover::BeginPlay()
{
Super::BeginPlay();
AActor* Owner = GetOwner();
FRotator ActorStartRotationThrowAway = Owner->GetActorRotation();
ActorStartRotation = ActorStartRotationThrowAway;
ActorStartRotation.Normalize();
ActorStartRotationQuat = FQuat(ActorStartRotation);
TargetRotation.Pitch = ActorStartRotation.Pitch + RotatorOffSet.Pitch;
TargetRotation.Yaw = ActorStartRotation.Yaw + RotatorOffSet.Yaw;
TargetRotation.Roll = ActorStartRotation.Roll + RotatorOffSet.Roll;
TargetRotation.Normalize();
TargetRotationQuat = FQuat(TargetRotation);
TargetRotationQuat = TargetRotationQuat * TargetRotationQuat.Inverse();
RotationSpeedQuat = ActorStartRotationQuat.AngularDistance(TargetRotationQuat) / TimeToRotate;
RotationSpeedBackQuat = TargetRotationQuat.AngularDistance(ActorStartRotationQuat) / TimeToRotate;
}
// Called every frame
void UMover::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
AActor* Owner = GetOwner();
FRotator CurrentRotation = Owner->GetActorRotation();
FQuat CurrentRotationQuat = FQuat(CurrentRotation);
FRotator TargetRotationBack = ActorStartRotation;
if (ActorStartRotation != TargetRotation) {
if (AreRotatorsApproximatelyEqual(CurrentRotation, ActorStartRotation, Epsilon)) {
AtTargetRotation = false;
AtStartRotation = true;
}
else if (AreRotatorsApproximatelyEqual(CurrentRotation, TargetRotation, Epsilon)) {
AtStartRotation = false;
AtTargetRotation = true;
}
}
if ((Swinger) && (!ShouldMove) && (ActorStartRotation != TargetRotation)) {
if ((AtStartRotation) && (!AtTargetRotation)) {
FQuat NewRotationQuat = FQuat::Slerp(CurrentRotationQuat, TargetRotationQuat, RotationSpeedQuat * DeltaTime);
if (CurrentRotation != ActorStartRotation) {
Owner->SetActorRotation(ActorStartRotation);
}
Owner->SetActorRotation(NewRotationQuat);
}
}
else if ((!AtStartRotation) && (AtTargetRotation)) {
ActorStartRotationQuat = ActorStartRotationQuat * ActorStartRotationQuat.Inverse();
TargetRotationQuat = FQuat(TargetRotation);
FQuat NewRotationBackQuat = FQuat::Slerp(CurrentRotationQuat, ActorStartRotationQuat, RotationSpeedBackQuat * DeltaTime);
Owner->SetActorRotation(NewRotationBackQuat);
}
}
}