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:

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.

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));
gAngle = (Mathf.Atan(yDist/xDist))*Mathf.Rad2Deg;
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;
this.gameObject.transform.localEulerAngles.z = rAngle;
}
//This is the GLOBAL rotation of the cannon base (cParent is the cannon parent that will rotate the whole object)
function RotateToShot(tBPos: Vector3) {
cParent.transform.LookAt(Vector3(tBPos.x, this.gameObject.transform.position.y, tBPos.z));
}