1
\$\begingroup\$

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);
}
\$\endgroup\$
3
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – wondra
    Aug 2, 2016 at 11:48
  • 1
    \$\begingroup\$ I will try to equation step by step. \$\endgroup\$
    – Marcel
    Aug 2, 2016 at 12:43
  • \$\begingroup\$ 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/… \$\endgroup\$
    – Cabrra
    Aug 2, 2016 at 20:17

1 Answer 1

0
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ 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? \$\endgroup\$
    – wondra
    Aug 3, 2016 at 20:46

Not the answer you're looking for? Browse other questions tagged .