Predictive Shooting Algorithm Needed

I’m working on some rudimentary AI for an arcade style aerial combat game. I need to calculate in 3d the angle to shoot at, based on the opponent continuing to move at the same velocity in the same direction.

The cannon shoots bullets straight which are not affected by air resistance or velocity.

The AI bot has a fixed position.
transform.position

The opponent has a fixed position right now, and is moving at a constant velocity (Vector3):
opponent.transform.position
opponent.rigidbody.velocity

The bullet travels at bullet_velocity (let’s say 200 m/s).

What I need is the angle to shoot the bullet at (quaternion) so it will intercept the target.

I’ve seen other posts with solutions, but they have complexities added such as gravity and angular velocity. I’m looking for something very simple.

I’m hoping there’s someone in the community who paid more attention in Trig class than I did!!!

Thanks,

  • Colin

This page was the most helpful to me when I was working on the same problem.

http://www.amoebasoid.com/tutorial/interception.htm

Thanks! This is the most helpful out of everything I’ve found on the internet, and looks like it solves exactly what I want to solve.

I’ll work on putting that solution into Unity code and will then post the result after I have it working… and ask for more help if I need it.

  • Colin

OK… using the above link (after studying trigonometry and quadratic equations) I put together the following code. The problem is it is way off.

http://www.amoebasoid.com/tutorial/interception.htm

Can someone please correct this and tell me what I am doing wrong?

function TrajectoryToTarget(pA : Vector3, pB : Vector3, vB : Vector3, sA : float) : Vector3 {
	// pA is the position of the cannon
	// pB is the position of the target
	// vB is the direction and velocity that the target is currently travelling
	// sA is the velocity that the bullet travels
	var neg_vB = -(vB);
	var dAB = Vector3.Distance(pB, pA);
	var cos_theta = (dAB * neg_vB.magnitude) / (Mathf.Abs(dAB) * Mathf.Abs(neg_vB.magnitude));
	var a = 1;
	var b = -(2*Mathf.Abs(neg_vB.magnitude) * cos_theta);
	var c = -(Mathf.Pow(Mathf.Abs(sA), 2) - Mathf.Pow(Mathf.Abs(neg_vB.magnitude), 2));
	var discriminant = Mathf.Pow(b, 2) - 4 * a * c;
	var root;
	if(discriminant > 0) root = 1;
	else if(discriminant == 0) root = -1;
	else if(discriminant < 0) root = 0;
	if(root != 0) {
		var vAB_abs = (-b + root * Mathf.Sqrt(discriminant)) / 2*a;
		var vAB : Vector3 = (pB-pA) / (dAB * vAB_abs);
		var vA : Vector3 = vAB - (neg_vB);
		return vA;
	} else {
		return Vector3.zero;
	} 
}

Thanks!

Has anyone had any success with this?