Slow Turn (For a Missile)

Hi guys! I just wanted to run my code by you guys and check what could be improved. This is the code I’ve used for a long time to get a missile to slowly turn towards a target. Is there an easier way? And, how would I add deltaTime to it??

    public Transform Target;
    public float turnSpeed;
    Quaternion LookRot;
    Vector3 Direction;
    void Update()
    {
        Direction = (Target.position - transform.position).normalized;
        LookRot = Quaternion.LookRotation(Direction);
        transform.rotation = Quaternion.Slerp(transform.rotation, LookRot, turnSpeed);
    }

Thank you for your time!

Quaternion.Slerp definitely don’t have turn speed as it’s argument. So generally your code is wrong.

take difference angle from your lookRotation and current rotation.
Than decompose it into angle and axis.
If (abs(angle) / deltaTime > turnSpeed) { //watch out for radians and degrees
angle = turnSpeed * deltaTime
Quaternion diff = now create Quaternion from this new angle and previous axis (this will be new difference)
lookRotation = diff * this.transform.rotation
}

Everything out of my head so it’s a little ugly

Also this solution don’t slow down rocket turning speed. But it might give you a good start.

BTW.
Pro programmers could use PID controller for this.

1 Like

Using Quaternion.Slerp has the interesting side effect of making the missile turn harder the more off-bore it is.

Using Quaternion.RotateTowards on the other hand takes a linear amount of degrees to change it by each frame.

To me often the former (Slerp) feels more natural: larger initial movements to get closer to where you want, then smaller movements as you approach boresight.

RotateTowards tends to produce perfectly circular orbits (assuming the missile is in flight as it corrects to turn), which can seem more contrived.

The important distinction between them is what that third term means. In RotateTowards it is degrees.

But in Slerp it is fraction, as in from 0.0f to 1.0f.

If you feed 1.0f in as the third term to Slerp, the missile will track instantaneously.

If you feed 0.5f in it will get halfway towards its desired angle each frame.

Neither of those is framerate independent.

If you pick a constant (I like to call this “snappiness”) to represent how quickly the missile turns, then you can integrate Time.deltaTime into it easily, while simply adjusting the value of snappiness to make it turn faster or slower.

public float turnSnappiness;  // try 2.0 to start with
// then the slerp:

transform.rotation = Quaternion.Slerp(transform.rotation, LookRot, turnSnappiness * Time.deltaTime);

NOTE: this technique can be applied to ALL forms of Lerp or Slerp: Mathf, Vector2, Vector3, Quaternion, Color, etc.

1 Like

Both of these replies were very useful for me, Thank you!
My question has been answered :slight_smile:

1 Like