So I have created spaceship shooter game where ships have turrets on them . Now I want those turrets to shoot a moving target meaning I want the projectile to intercept and hit the target that is headed in some direction. Every projectile has its own speed which is constant. Also the ship which has the turret is also moving at a constant speed.

So far I have made this:

Vector2 toTarget = targetShip.GlobalPosition - Player.currentShip.GlobalPosition;
            Vector2 targetVel = ( targetShip.dir.Normalized() * targetShip.speed * delta) - (Player.currentShip.dir.Normalized() * Player.currentShip.speed * delta);
            float distance = toTarget.Length();

            float a = targetVel.Dot(targetVel) - (projectile.speed * projectile.speed);
            float b = 2 * targetVel.Dot(toTarget);
            float c = -distance * distance; //toTarget.Dot(toTarget);

            float p = -b / (2 * a);
            float q = Mathf.Sqrt((b * b) - 4 * a * c) / (2 * a);

            float t1 = p - q;
            float t2 = p + q;

            if (t1 < 0 && t2 < 0)

            float timeToInterception = 1;
            if (t1 > 0 && t2 > 0)
                timeToInterception = Mathf.Min(t1, t2);
                //timeToInterception = Mathf.Max(t1, t2);

            Vector2 aimSpot = targetShip.GlobalPosition + targetVel * timeToInterception;
            dir = aimSpot - GlobalPosition;
            GlobalRotation = Mathf.LerpAngle(GlobalRotation, dir.Angle(), turnRate * delta);

The Global Rotation is where the turret will look at and it shoots from its barrel. The method kinda works and sometimes does not work(the projectiles shoot behind the moving target). Vector2 targetVel = ( targetShip.dir.Normalized() * targetShip.speed * delta) - (Player.currentShip.dir.Normalized() * Player.currentShip.speed * delta); that part is me calculating velocities I am not sure if its correct...

I commented out the else part because the turrets just disappear from my ship if I let that be there and I am also uneducated why.

I've read THIS answer from this forum but I don't understand it especially his edit part. In his edit part I don't understand where to plug that projectile velocity. Also why is my turret disappearing when I uncomment else in my code?

If someone can give me some explanation I would be very thankful!

  • \$\begingroup\$ Can you clarify what it is about the linked answer you don't understand? It seems to just be describing a standard relative velocity calculation (subtract the velocity of the frame of reference from the velocity of each entity to get their velocities relative to that frame of reference). Where do you run into trouble applying that, or other past Q&A about calculating intercept velocities/target leading? \$\endgroup\$
    – DMGregory
    Nov 27, 2022 at 23:51
  • \$\begingroup\$ Hey yea just did it in an edit. \$\endgroup\$
    – GoldSpark
    Nov 27, 2022 at 23:53
  • \$\begingroup\$ The answer does not talk about that. It's just talking about how to take the "moving shooter" out of the equation, so you can use existing answers about aiming at a moving target from a stationary shooting point. You can consult past Q&A like 1, 2, 3, 4, and more (those were just the first few results I found searching for "target leading" and "intercept moving"). \$\endgroup\$
    – DMGregory
    Nov 28, 2022 at 0:09
  • \$\begingroup\$ Thank you I will look into it. \$\endgroup\$
    – GoldSpark
    Nov 28, 2022 at 0:11
  • \$\begingroup\$ @DMGregory I am wondering am I getting velocity vector calculation right? \$\endgroup\$
    – GoldSpark
    Nov 28, 2022 at 13:56

1 Answer 1



This tutorial helped me and it works great now! Thanks @DMGregory for the link!

This is how my code looks now:

Vector2 toTarget = (targetShip.GlobalPosition) - GlobalPosition;
                Vector2 targetVel = (targetShip.dir.Normalized() * targetShip.speed);
                Vector2 gunVelocity = (ownerShip.dir.Normalized() * ownerShip.speed);
                Vector2 vr = targetVel - gunVelocity;

                float t = AimAhead(toTarget, vr);

                if (t > 0f)
                    Vector2 aimPoint = targetShip.GlobalPosition + targetVel * t;
                    dir = aimPoint - GlobalPosition;
                    GlobalRotation = Mathf.LerpAngle(GlobalRotation, dir.Angle(), turnRate * delta);

The function AimAhead is the one that calculates everything:

float a = vr.Dot(vr) - (projectile.speed * projectile.speed);
        float b = 2 * vr.Dot(toTarget);
        float c = toTarget.Dot(toTarget);

        float det = b * b - 4 * a * c;

        if (det > 0f)
            return 2 * c / (Mathf.Sqrt(det) - b);
            return -1f;
  • \$\begingroup\$ Remember to click the "Accepted" checkmark in the upper left if this answer solved your problem. \$\endgroup\$
    – DMGregory
    Dec 9, 2022 at 21:41
  • \$\begingroup\$ This solution is obviously wrong since if targetVel is 0 then you're doing nothing to compensate for the gunVelocity \$\endgroup\$
    – shoosh
    Jun 10 at 21:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .