# Projectile motion - strange behavior

Hi!

I am currently working on an RTS cannon script. The idea is to have the cannon automatically calculate the angle required to hit the target, but I am receiving strange behavior from the cannon when the target is above 45 degrees. Currently, this script only works in 2D and the positive root is shown:

``````xDist = Mathf.Abs(this.gameObject.transform.position.x - tPos.x);
yDist = tPos.y - this.gameObject.transform.position.y;
rAngle = (Mathf.Atan((Mathf.Pow(pVel, 2.0) + Mathf.Sqrt(Mathf.Pow(pVel, 4.0) - pGravity*(pGravity*Mathf.Pow(xDist, 2.0) + 2.0*yDist*Mathf.Pow(xDist, 2.0))))/(pGravity*xDist)))*Mathf.Rad2Deg;
``````

The equation that I am using can be found here:
equation

If the target has the same ‘y’ position, both roots of the equation work.

If the target is above 45 degrees, both roots of the equation do not hit the target.

Once the target has returned below the 45 degree mark, both equations hit the target perfectly.

This is not a huge issue (I originally planned on capping the angle at 45 degrees), but I would be interested if someone could explain this strange behavior.

Your equation is slightly wrong. Where you should have 2yv^2 term under the square root, you have 2yx^2.

Corrected rAngle code…

``````rAngle = (Mathf.Atan((Mathf.Pow(pVel, 2.0) + Mathf.Sqrt(Mathf.Pow(pVel, 4.0) - pGravity*(pGravity*Mathf.Pow(xDist, 2.0) + 2.0*yDist*Mathf.Pow(pVel, 2.0))))/(pGravity*xDist)))*Mathf.Rad2Deg;
``````

You should also check that the sign of the term under the square root is positive. If it’s negative, then no solution exists for the given variables.

Thanks! Careless mistake on my part.

Here is the code for a ‘working’ cannon that can calculate the proper angle now:

``````//This is the code for the cannon itself that will find the angle based on height and distance
//gAngle is the angle created by the distance and height of the target
//rAngle is the angle the cannon has to rotate towards to hit the target
function CalculateShot(tPos: Vector3, pVel: float, pGravity: float) {
var xDist: float;
var yDist: float;
var hDist: float;
var gAngle: float;
hDist = Vector3.Distance(this.gameObject.transform.position, tPos);
yDist = tPos.y - this.gameObject.transform.position.y;
xDist = Mathf.Sqrt(Mathf.Pow(hDist, 2) - Mathf.Pow(yDist, 2));