Where to aim if you want to hit a moving target considering bullet drop


I had to put some work into the code to get the units to hitting their enemys, but now it works quite fine:

The launching speed of the projectile is fixed, so the correct angles (in two directions) have to be calculated to hit the target just at the position it will be in a few seconds. Time in air in this example is nearly 5 seconds - the projectile just follows its ballistic curve, there are no adjustments made after it‘s been released. Works well as long as the target does not change its velocity vector.

The math behind it:

We have to know the position of the gun, the (launch) velocity of the projectile, the position and current speed of the target. We are looking for a vector representing the direction the projectile will be launched.

It's an iterative approach for a world without air resistance. Also, there are two solutions, one below (cannon) and one above (e.g. mortar) 45°; here, we are looking for the solution below 45°. There might be some problems if the y-axis-distance between gun and target is larger than the xz-plane-distance.

  1. Calculate how long the projectile (just flying in a straight line) would take to hit the target in its current position. Then calculate where the target will be at that time ("effective position") and the distance of this point from the gun (= "effective distance"). It's an rough first estimation, but it's ok for a starting point.
    1. We now can calculate an updated time for the proectile to hit the target at the new effective distance. Using the updated time, we can calculate an updated effective distance. Repeating this step 3 times was enough for me to get a good result. However, bullet drop is not yet considered.
  2. Until now, were not considering bullet drop, so the projectile will reach the point of the effective position at a y-position that is below the target. We can calculate that distance, it's -10/2 * t^2 (for g = 10). So we should add this distance to the effective position and aim a bit higher ("effective position considering bulllet drop"). But now, the projectile will take longer to reach the target, as it is flying a curve and not a straight line. But we can calculate a new approximation of the "effective speed" (the factor is sin(angle between the aim vector and the up vector). Using the new effective speed, we can start from the beginning.

Three iterations of the whole thing, with three iterations of 1.a. each time, works just fine in my case.

My solution was implemented in Unity, but the idea behind it should work for other engines too.


Code example you can reuse for your project ("aimDir" is the aiming vector of the gun, we are looking for this):

Vector3 targetSpeed = currentTarget.GetComponent<Unit>().speed;

float angle;

float effProjectileSpeed = projectileSpeed;

for (int i = 0; i < 3; i++)

{

    float calcHitDistance = Vector3.Magnitude((currentTargetPos + (targetSpeed) * (Vector3.Distance(currentTargetPos, projectileSpawn.transform.position) / effProjectileSpeed) - projectileSpawn.transform.position));

   

    for (int j = 0; j < 3; j++)

        {

       calcHitDistance = Vector3.Magnitude((currentTargetPos + (targetSpeed) * (calcHitDistance / effProjectileSpeed) - projectileSpawn.transform.position));

       }


    aimDir = Vector3.Normalize(currentTargetPos + (targetSpeed) * (calcHitDistance / effProjectileSpeed) - projectileSpawn.transform.position + 5 * Mathf.Pow(calcHitDistance / effProjectileSpeed, 2) * Vector3.up);

    angle = Vector3.Angle(Vector3.up, aimDir);

    effProjectileSpeed = projectileSpeed * Mathf.Sin((Mathf.PI / 180) * angle);

}

Get 6 APM

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.