Constant rotation drift towards fixed direction

I’ve got a pawn that I need to always be rotating slowly rotating towards a certain point (straight down in this case). Right now I’m adding player input to current local rotation to control the pawn, but I haven’t been able to figure out how to add this downward pull every tick.

FMath::RInterpTo

Assuming you figured out the rotation that you need to rotate to, just call it every frame like this:

FRotator NewRotation = FMath::RInterpTo( CurretRotation, DesiredRotation, DeltaTime, InterpSpeed);

The problem is that I can’t seem to generate a rotator that acts the way I want it to. I know the vector, but that’s a world vector, not a local one, and I can’t seem to get a rotator that will line up the local forward vector with the world 0,0,-1 vector.

The FindLookAtRotation() should be the answer to this, but I can’t get it to do anything useful.

I’m obviously missing something, and/or going about this in the wrong way, but I’m not even sure where to start, I feel like I’ve tried every possible combination of ways to go about this.

FindLookAtRotation looks at a location, if you want to just straight down, try using Make Rotator From XZ

just put in your forward vector and (0,0,-1) for Z and you should have what you want - didn’t try it though, so it might be one of the other options (ZX, XY or something)

Okay, so I couldn’t get it to work with MakeRotatorFrom__, but I did get it 90% working by going over it twice, setting the world rotation down making sure to keep the global yaw and roll the same, and then the local input rotation.

FTransform Trans = ShipMeshComponent->GetRelativeTransform();
Trans.ConcatenateRotation(FRotator(PitchInput, 0.0f, RollInput).Quaternion());
ShipMeshComponent->SetWorldRotation(Trans.Rotator());
    
FRotator CurrentRotator = ShipMeshComponent->GetComponentTransform().GetRotation().Rotator();
FRotator TestRotator = FRotator(-90.0f, WorldYaw, WorldRoll);
ShipMeshComponent->SetWorldRotation(FMath::RInterpConstantTo(CurrentRotator, TestRotator, DeltaTime, 10).Quaternion());

This does exactly what I want, but with the unfortunate quirk of some weird, inconsistent stuttering while rolling and pointing directly down, though I’m not quite sure what’s causing it. First guess would be it’s something to with quaternions, or lack-there-of.

This is actually somewhat workable, because the stuttering doesn’t seem to affect control, it’s more of a visual glitch than anything, just tweaks out for a frame before returning to where it should be, and in practice the pitch-down slows (not in the code above, mind you) as you reach up/down apexes, so chances of excessive rolling happening while pointing directly down are extremely low, but I also feel it could be indicative of an issue I’m not yet aware of, so ideally I’d like to solve it.

You are setting ShipMeshComponent->SetWorldRotation() twice in the same function I believe.
Line 3 and line 7.
Not sure if that is the same function though, but that could explain the stuttering.

also one thing to note, you can just call Component->GetRotation(), no need to always query the transform and then convert quaternions to rotators and vice versa.

Yeah, the logic is that it sets input rotation, and then sets the drift rotation afterwards on the new location. I tried composerotators, and multiplying them as quats and it doesn’t add them as I would have expected. I would think if you add 2 rotators together (or multiply the quats) they would give a rotator that is the same as applying both of them in sequence, but that’s apparently not the case.

I did change the rotations there to just getting them by the actor (need to do the actor, not the mesh, but the mesh also happens to be the root in this case, which is probably not best practice), all that still works, and the added .quaternion() there was mostly just left in to see if it made a difference with the stuttering, which it did not.