Mathf.LerpAngles overshoots

I am trying to get 2 objects to have a rotation relative to each other. More specifically, the player and the rest of the world.

The following script is what I’ve gotten to work so far, but it has issues.

    float rotation = 
      1.0f / //invert the number (was always lower at begining but gets bigger the closer I got to the desired rotation, which is unpleasant)
      ( TheWorld.transform.rotation.eulerAngles.z - //current world angle
        Mathf.LerpAngle( 
            TheWorld.transform.rotation.eulerAngles.z, // from current world angle
            currentAngle - transform.eulerAngles.z , // to desired angle
            Time.deltaTime / 2f ) ); // speed parameter to make it framerate independent


 TheWorld.transform.RotateAround( transform.position, runDirectionAxis , rotation ); // rotate around the player position, along the current world forward axis, bz calculated angle

For starters, it isn’t very nice looking, but more importantly, the screen jitters back and forth as this seems to overshoot the desired position. Not by a lot, but by enough to be visually disturbing.

My attempt to make it more clear:

A is the player. A doesn’t move.

B is a tube. B rotates around A. B needs to know which way is down depending on currentAngle.

Script is appended to A.

Your code is a little odd. To understand it a little better, this is what you’re actually doing (assuming transform.eulerAngles.z is player angle, and the average time step is 1/60th of a second):

world_angle - lerp(world_angle, current_angle - player_angle, 1/60)

= world_angle - (world_angle * 1/60 + (current_angle - player_angle) * 59/60)

= world_angle * 59/60 + (player_angle - current_angle) * 59/60

So each frame you’re reducing the world angle a bit, and adding on some extra stuff. Unless you’re very lucky, I’d be surprised if you didn’t seem some sort of odd behaviour that might appear to be overshoot.

Can’t say exactly what it should be without knowing a little more, but I suspect you just want something along the lines of:

new_world_angle = Mathf.LerpAngle(current_world_angle, target_angle, Time.deltaTime)

Which will gradually draw the world angle towards the target. As we’re passing in a fixed value as the interpolator, it’ll appear to slow down as you get closer, as each frame you’re just moving a fixed fraction of the distance between where you are and where you want to be.

If you wanted to move at a constant speed (instead of slowing down gradually), you’d need to store the initial world angle somewhere, then it’d be:

new_angle = Mathf.LerpAngle(initial_angle, target_angle, interpolator)

Where interpolator is a value that goes from 0 to 1, probably increasing over time.