How to ROTATE an object without slowing the ends (lerp)

I know Linear Interpolation slows down the ends because that’s just how it works. However I’m trying to make a character turn to face a point over the course of roughly 0.33 seconds.

I’ve tried using normalize, Math.smothStep, Lerp, Slerp, Vector3.MoveTo, etc. I have googled this and tried many things but everything has an issue. Some have the smoothing at ends, others are not accurate enough, fast enough, slow enough, etc.

I just want to make my character smoothly rotate and look at a point at a consistent speed

My code right now, in Update() (that slows the ending):

float speed = 5f;
Quaternion rotationToLookAtNode = Quaternion.LookRotation(node.transform.position - this.gameObject.transform.position);
transform.rotation = Quaternion.Lerp(transform.rotation, rotationToLookAtNode, speed * Time.deltaTime);

Slerp (Lerp) from a rotation to a target rotation. What you’re doing is rotating from the current rotation to the target rotation, which is constantly getting smaller as you get closer. You need to record the rotation at the time you initiated the rotation, and modify the third argument so it goes 0-1.

IEnumerator RotateTo(Quaternion target) {
  Quaternion from = transform.rotation;
  for ( float t = 0f; t < 1f; t+= speed*Time.deltaTime ) {
    transform.rotation = Quaterion.Lerp(from,target,t);
    yield return null;
  }
  transform.rotation = target;
}

Since you are performing the lerp every frame from the current value (transform.rotation), you will be acting on a distance that is shrinking every frame, so you will indeed see the rotation slow as you get closer to the end, because the value you are passing to the sleep for the amount (the speed) will be constant for the most part (yes not really, but it is very close as long as all of your frames are about the same time apart). So let’s just assume this rate * time.deltaTime is about 0.5 for simplicity. In the first frame, you slerp to 50% of the full rotation. In the second frame, you slerp 50% of What Remains in the rotation, so you can see as frames continue, you continue to slerp 50%, but the rotation amount becomes smaller and smaller.

To fix this, capture the starting rotation at the beginning and use that as the first parameter every frame. Also, simply slerp from 0.0 to 1.0, which is actually the intended use of the lerp and slerp methods, though many people use them in the way you have to ease in and out, which you don’t want. So, in frame 1, pass in 0.0, in frame 2, pass in 0.1, in frame 3, 0.2, etc. for the third parameter to lerp. Also, I would do this in the FixedUpdate, though not necessary, but if you do it in Update, it would require the time.deltaTime correction, so you would increase the third parameter by say rate * time.deltaTime every frame, limiting it to 1.0, where rate is around 2 if you wanted the rotation to be about 3% every frame at 60 hz.

I use this code for homing projecties:

 public float rotationSpeed = 200f;
 public float speed = 20f;
    public Transform followMe;
    void FixedUpdate()
    {
        Quaternion q = new Quaternion();
        q.SetLookRotation(followMe.position - transform.position);
        transform.rotation = Quaternion.Slerp(transform.rotation,q, 1f / Quaternion.Angle(transform.rotation, q) * Time.fixedDeltaTime * rotationSpeed);
        transform.position += transform.rotation * Vector3.forward * speed * Time.fixedDeltaTime;
    }