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\$
  • 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 '16 at 11:48
  • 1
    \$\begingroup\$ I will try to equation step by step. \$\endgroup\$ – Marcel Aug 2 '16 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 '16 at 20:17
1
\$\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.

| improve this answer | |
\$\endgroup\$
  • \$\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 '16 at 20:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.