Required initial velocity (fixed launch angle) for projectile to hit a target

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 to Mathf.Tan. Rather than doing the math that way, and having to "just know" that 360 - this.turretTransform.eulerAngles.x is the angle, you could use the components of this.turretTransform.forward to calculate tanG directly. – Victor T. Apr 1 '17 at 21:01
• Victory! Now it's working as it should. Can you please post this as an answer so I can accept it? :) – Majster Apr 1 '17 at 21:17

turretAngle is in degrees, so you need to convert it to radians before passing it to Mathf.Tan.
Rather than doing the math that way, and having to "just know" that 360 - this.turretTransform.eulerAngles.x is the angle, you could use the components of this.turretTransform.forward to calculate tanG directly. That would be
Vector3 forward = this.turretTransform.forward;

• Thanks again. If it's not too much of a hassle would you mind also explaining why can you calculate the tanG directly like that? I know it's probably basic linear algebra but I can't seem to wrap my head around it. – Majster Apr 2 '17 at 7:09
• Ok I figured it out. For anyone else interested: It's the basic tan(∂) = opposite_side / adjacent_side. And in this case the opposite side is the height forward.y and the adjacent side is calculated by using the pythagorean theorem. – Majster Apr 2 '17 at 9:12