Why does RInterpToConstant not point actor towards target rotation?

I’m using a very simple GetLookAtDirection and an RInterpToConstant in a BP. I thought it would simply turn my missile actor towards the target but it doesn’t seem to do it consistently.

I have a debug line drawing the look at direction which always points straight towards the target. When the missile actor gets close to the target it turns away and then proceeds to move around the target in a flat circle.

I understand with limited turning you could get into that circle state but why does the missile turn away from it’s target as it gets close. It seems to happen when the path is at a near vertical descent but it can but 10-20 degrees off of the straight down and it will still turn away as it approaches the target instead of continuing to turn towards it.

Why is RInterpToConstant behaving this way?

BP:


Missile Trail:


The rotation speed would probably need to increase with the distance between the actor and missile getting shorter, so that the turns can be tighter.

You could to a remap value with a max in min distance giving a new turn factor for the missile.

The initial turn speed is enough to hit the target. I understand getting stuck in a circle but the problem is why does the projectile initially turn away from its goal?

Could the position of the target be invalid?
You could cache the position and then smooth out the target position by doing an average of the cache of the last 2 frames and the current frame. Then you would not get any vector spikes.

if the look at rotation is not in quaternions then perhaps it flips que to gimbal lock?

The target is stationary and the debug line always shows the correct desired rotation. It looks like a euler angle failure thing but I was under the impression that the BP rotator nodes used quaternions in their implementations so you didn’t need to worry about that unless you were manually manipulating rotators.

I’ll just rewrite it in c++ using quats and see what happens.

Seems to internally use make rotation from x and subtracts the positions and returns basic FRotators so no FQuats.

So, interesting, i did a simple quaternion slerp and used the result to set actor rotation and I get a very similar behavior.

const FVector DeltaPos = Target->GetActorLocation() - GetActorLocation();
const FQuat TargetQ = DeltaPos.ToOrientationQuat();
	
const FRotator Rot = GetActorRotation();
const FQuat Q = Rot.Quaternion();

SetActorRotation(FQuat::Slerp(Q, TargetQ, .05));

Something fundamental I must be misunderstanding.

hmissile.zip (75.7 KB)

Example project with your code slightly modified (variable turn rate)

Thank you for the example. You can overcome this by simply increasing the possible rate of turn but that doesn’t seem address the underlying problem.

I think what is happening here is that the rotation I’m creating from the delta of the positions always has no roll considered. When the missile is approaching an inversion the interpolation to the new angle begins to be dominated by roll.

I tried out the quaternion find between vectors and used that to slerp towards a target. Gave me some weird behavior but I need to setup a better system to use the results there instead of just slerping towards the multiplied current quat and delta quat.


Oh I think I just multiplied them in the wrong order :). This is the kind of behavior I would expect.


const FVector DeltaPos = Target->GetActorLocation() - GetActorLocation();
const FQuat TargetQ = FQuat::FindBetweenVectors(GetActorForwardVector(), DeltaPos);
	
const FRotator Rot = GetActorRotation();
const FQuat Q = Rot.Quaternion();

SetActorRotation(FQuat::Slerp(Q, TargetQ*Q, .05));
1 Like