Download

There seems to be a bug with GetWorldRotation on a component at absolute Yaw of 180deg(Gimbal lock?)

So I have some arrows placed in the world and a track is created randomly with 90 degree turns. The track sections are all the same, one straight, one left, and one right turn.

Basically, my pawn enters a BP box trigger, which calls a function in my pawn’s CPP class, passing it the world rotation of the arrow, which I then use to add rotation to my pawn to match.

100% of the time, when my pawn reaches the left turn that is aligned to 180 degrees, the control freaks out and it snaps back and forth to 180 in the wrong direction for a split second, then snaps back to the correct direction.

This only happens when the track is aligned to Absolute 180degrees. I printed some debug messages to the screen that will only print if the math results in the pawn being told to rotate more than 90 degrees (since it shouldnt even be able to hit 90 as I am applying it in two 45’s).

I noticed the debug message always says the track rotation.Yaw = 179.999939.


const FRotator ActorRotation = GetActorRotation();
		const float DesiredYaw = (TrackAlignment.Yaw - ActorRotation.Yaw);
		if (FMath::Abs(DesiredYaw) > 90.f)
		{
			
			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Ship: %f, Track: %f, Des: %f"), ActorRotation.Yaw,TrackAlignment.Yaw, DesiredYaw));

		}
		FRotator DeltaWorldRot(0, 0, 0);
		DeltaWorldRot.Yaw = FMath::FInterpTo(0.f,DesiredYaw, DeltaSeconds, 10.f);
		DeltaWorldRot.Pitch = (TrackAlignment.Pitch - ActorRotation.Pitch) * DeltaSeconds;
		AddActorWorldRotation(DeltaWorldRot);

Is this some odd gimbal lock issue, or is there some other math error or problem with the target world rotation being close to 180deg?

Like I said, this same section of track and code has no problem applying the other turns, and in the end, this gives me the proper rotation. It is just briefly snapping the pawn to 180deg in the wrong direction for a frame or two.

Okay so the issue appears to be when the rotation is transitioning between +170 something degrees to the -180deg.

Is there a built in function to get the shortest angle between two? Or else I need to always check which is about to cross the 180 threshold.