The scenario:
I have an enemy tank (AI) chasing my friendly tank (player). When the enemy gets close enough he tries to shoot the player. Now the enemy prefab has an empty game object attached as a child which is used as the projectile (shell) spawn point. It's tilted 10 degrees up (X axis, the actual value in inspector is 350).
Example:
Now I'm trying to figure out what velocity or force must I apply to the projectile in order to hit the player. The angle is fixed (10 degrees) and is always the same. I have tried using the equation (from wikipedia):
Which I solved for v
and got:
and translated into code which looks like this:
private float requiredForceToHit(Transform target)
{
float turretAngle = 360.0f - this.turretTransform.eulerAngles.x; //Turret is 10 deg tilted up (350 in inspector)
float g = Physics.gravity.magnitude; //G force
float y = 0.0f; //Height of the target
float x = Vector3.Distance(target.transform.position, this.turretTransform.position); //distance to hit, slight off because turret is lifted up
float tanG = Mathf.Tan(turretAngle);
float upper = Mathf.Sqrt(g) * Mathf.Sqrt(x) * Mathf.Sqrt(tanG * tanG + 1.0f);
float lower = Mathf.Sqrt(2 * tanG - ((2 * y) / x));
float velocity = upper / lower;
return velocity;
}
But the projectile falls short from the target. It does launch farther when farther away but the farther away the target the more distance between the point of shell impact and the actual target. What I'm trying to say is that it is pushing with greater velocity the farther away I am but it falls short.
What is wrong and how do I fix it?
Appendix:
The actual shooting code:
private void fire(float force)
{
Rigidbody shellInstance = Instantiate(this.shell, this.turretTransform.position, this.turretTransform.rotation) as Rigidbody;
shellInstance.velocity = this.turretTransform.forward * force;
}
turretAngle
is in degrees, so you need to convert it to radians before passing it toMathf.Tan
. Rather than doing the math that way, and having to "just know" that360 - this.turretTransform.eulerAngles.x
is the angle, you could use the components ofthis.turretTransform.forward
to calculatetanG
directly. \$\endgroup\$