1
\$\begingroup\$

I am trying to do a simple AI Controller, which fires Missiles at the surrounding targets in the Scene.

  • The AI Controller can fire projectiles when moving or stationary.
  • The Targets are either stationary or move around in the scene with a Constant Velocity and can't fire projectiles.

I did some searching on Stack overflow and came up with this code to find the direction the AI controller must fire the projectile (constant speed) to hit a target travelling at a constant velocity(it can also be stationary):

private bool GetProjectileDirection(GObject target, GObject source, out Vector3 direction) { // Initialize direction to Zero direction = Vector3.zero; // The Relative Position between the AI Controller and the target. Vector2 w = new Vector2(target.Position.x - source.Position.x, target.Position.y - source.Position.y); // The Relative Velocity between the source and the target. Vector2 v = new Vector2(target.Velocity.x - source.Velocity.x, target.Velocity.y - source.Velocity.y); // Quadratic Equation Co-efficients float a = Vector2.Dot(v, v) - BULLET_SPEED * BULLET_SPEED; float b = Vector2.Dot(w, v); float c = Vector2.Dot(w, w); float root = (b * b) - (a * c); // The Problem seems to occur here as this becomes less than zero most of the time, // and exits the function. // But on the screen, the object is well within the range for the AI to fire at it if (root < 0) return false; // If root < 0, then this becomes NaN and brings the simulation to a crawl double t = (-b - Math.Sqrt(root)) / a; double shootX = w.x + t * v.x; double shootY = w.y + t * v.y; double theta = Math.Atan2(shootY, shootX); direction = BULLET_SPEED * new Vector3(Math.Cos(theta), 0, Math.Sin(theta)); return true; } 

I am pretty sure I am missing something. I just can't pinpoint what exactly is it. As a result, the AI seems to miss most of the targets around it.

\$\endgroup\$
7
  • \$\begingroup\$ Looks like you may have forgotten to add the launcher's velocity to its projectile on firing. \$\endgroup\$ Commented Sep 22, 2019 at 12:30
  • \$\begingroup\$ @DMGregory But most of the time the Execution doesn't even reach the part of the Code. The code returns at the line if(root < 0). \$\endgroup\$ Commented Sep 22, 2019 at 12:34
  • 1
    \$\begingroup\$ That usually means your bullet speed is too low. We can check the math though to see if there's an error in the formula. \$\endgroup\$ Commented Sep 22, 2019 at 12:36
  • \$\begingroup\$ Okay! Let me check! \$\endgroup\$ Commented Sep 22, 2019 at 12:36
  • \$\begingroup\$ @DMGregory Okay! You were right. Increasing the Bullet speed resulted in the Projectiles being fired! But the Accuracy is all over the place! \$\endgroup\$ Commented Sep 22, 2019 at 12:41

1 Answer 1

2
\$\begingroup\$

This is the updated code, with code for handling some edge cases. Also, I made sure the BULLET_SPEED large enough for the Equations to work:

 private bool GetProjectileDirection(GObject target, GObject source, out Vector3 direction) { direction = Vector3.Zero; Vector2 w = new Vector2(target.Position.x - source.Position.x, target.Position.y - source.Position.y); float ww = Vector2.Dot(w, w); float r = target.BoundingRadius; Vector2 v = new Vector2(target.Velocity.x - source.Velocity.x, target.Velocity.z - source.Velocity.z); double a = Vector2.Dot(v, v) - (BULLET_SPEED * BULLET_SPEED); double b = 2 * Vector2.Dot(w, v); double c = Vector2.Dot(w, w); double h = -b / (2 * a); double k2 = h * h - (c / a); double t = 0.0f; if (k2 < 0) return false; if (k2 == 0) { if (h > 0) t = h; else return false; } if (k2 > 0) { double k = Math.Sqrt(k2); double r0 = h - k; double r1 = h + k; if (r0 > 0) t = r0; else if (r1 > 0) t = r1; else return false; } double shootX = w.x + t * v.x; double shootY = w.y + t * v.y; double theta = Math.Atan2(shootY, shootX); direction = new Vector3(Math.Cos(theta), 0, Math.Sin(theta)); return true; } 

Here is the answer that I based this code off.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.