BUILDING PROPORTIONAL NAVIGATION MISSILE GUIDANCE IN UNITY

The physics and C# algorithms behind smart heat-seeking missiles, line-of-sight rate calculation, lead pursuit intercepts, and countermeasure decoy flares.

1. Why Pure Pursuit Fails in Air Combat

Novice developers often code homing missiles using Pure Pursuit (simply rotating the missile directly toward the target's current position via transform.LookAt(target)).

In supersonic aerial combat, pure pursuit causes the missile to continually lag behind a crossing aircraft. As the target turns, the missile enters a tight tail-chase death curve with ever-increasing G-force demands until it overshoots and runs out of fuel.

Real aerospace missiles (like the AIM-9 Sidewinder) use Proportional Navigation (PN): the missile's turning rate is directly proportional to the rotation rate of the Line-of-Sight (LOS) vector between missile and target. This commands the missile to fly toward a predicted intercept point ahead of the target.

2. Production Proportional Navigation Script

Here is a high-performance C# implementation suitable for combat flight games:

using UnityEngine;

public class ProportionalNavMissile : MonoBehaviour
{
    [Header("Missile Kinematics")]
    [SerializeField] private float speed = 120f;
    [SerializeField] private float navigationGain = 3.5f; // Proportional constant (usually 3.0 - 4.5)
    [SerializeField] private float maxTurnRate = 180f; // Max degrees turned per second

    [Header("Target Tracking")]
    [SerializeField] private Transform target;

    private Vector3 previousLosVector;

    private void Start()
    {
        if (target != null)
        {
            previousLosVector = (target.position - transform.position).normalized;
        }
    }

    private void FixedUpdate()
    {
        // 1. Move forward along current trajectory
        transform.position += transform.forward * speed * Time.fixedDeltaTime;

        if (target == null) return;

        // 2. Compute current Line-of-Sight vector
        Vector3 currentLos = (target.position - transform.position).normalized;

        // 3. Compute Line-of-Sight angular rotation rate (Omega)
        Vector3 losDelta = (currentLos - previousLosVector) / Time.fixedDeltaTime;
        previousLosVector = currentLos;

        // 4. Proportional Navigation commanded acceleration vector
        Vector3 commandedTurn = losDelta * navigationGain;

        // 5. Apply turn with max angular rate clamp
        Vector3 desiredForward = (transform.forward + commandedTurn * Time.fixedDeltaTime).normalized;
        Quaternion targetRotation = Quaternion.LookRotation(desiredForward);
        
        transform.rotation = Quaternion.RotateTowards(
            transform.rotation, 
            targetRotation, 
            maxTurnRate * Time.fixedDeltaTime
        );
    }
}

Related Combat Guides & Calculators