How to calculate the ideal hit of arrow?

I am trying to make the AI shoot an arrow and always hit the target. Assuming that the target is within his range I am stuck what the correct way is to do this. I search and found some solutions but they do not seem to work 100% perfectly in my code (How can I shoot an arrow if I know the shot power and target?).

My code is (target is the prefab I want the AI to hit):

arrow.GetComponent<Rigidbody>().AddForce (Aim()*speed, ForceMode.VelocityChange);

private Vector3 Aim()
{
float xAim = target.transform.position.x - transform.position.x;

float yAim = Mathf.Rad2Deg * Mathf.Atan((speed*speed + Mathf.Sqrt(speed*speed*speed*speed) - (-Physics.gravity.y) * (-Physics.gravity.y * HorizontalDistance()*HorizontalDistance()) + 2 * VerticalDistance() * speed*speed / -Physics.gravity.y * HorizontalDistance()));
float zAim = target.transform.position.z - transform.position.z;
Vector3 aim = new Vector3(xAim, yAim, zAim).normalized;
return aim;
}
private float HorizontalDistance()
{
float xDistance = target.transform.position.x - transform.position.x;

// float zDistance = target.transform.position.z - transform.position.z;
float distance = Mathf.Sqrt(xDistance*xDistance);// + (zDistance*zDistance));

return distance;
}
private float VerticalDistance()
{
return Mathf.Abs(target.transform.position.y - transform.position.y);
}

• Are you aware that the code you posted is not of the equation you linked? More over there are rather strange/redundant operations like Mathf.Sqrt(speed*speed*speed*speed)  which will always be equal to speed*speed. Try assembling the equation step by step, not on one line - it should help. – wondra Aug 2 '16 at 11:48
• I will try to equation step by step. – Marcel Aug 2 '16 at 12:43
• To make your life easier you could "cheat" it a little and make the arrow go towards the target with a little drop physics. Or another valid and better solution would be using the impact point to calculate the proper arc-> gamedev.stackexchange.com/questions/17467/… – Cabrra Aug 2 '16 at 20:17

Thanks wondra, solved the issue by splitting everything and to translate the formula to C#:

where posX and posY is the target x and y where g is de phycics gravity where speed is the value I want to fill in.

Now I have the angleZ to put in my arrow Vector3

float s = Mathf.Sqrt((speed * speed * speed * speed) - g * (g * (posX * posX) + 2 * posY * (speed * speed)));
float angleZ = Mathf.Atan(((speed * speed) + s) / (g * posX))*Mathf.Rad2Deg;


I only still have the problem when y is not 0. The formula I now used only works if y=0. Have not found the correct formula so I can get the correct angle even when y is different from eachother.

• I am afraid the formula is actually for x,z coordinates(as you defined them), it is not supposed to work for shooting "diagonally" from top view. As for now it is ambiguous whether y is for shooting "diagonally" from top view or shooting target that is lower/higher than the archer. Which option is your case? – wondra Aug 3 '16 at 20:46