- Home /
Tower Defense: Calculate Force of projectile depending on Enemy position
Hi everybody,
I want to make a Tower Defense game and I was questioning how to calculate the force of the projectile depending on the position of an Enemy. I made a little sketch to show how I wanted to shoot the projectile. I want to fire the projectile without any tilt, because otherwise the arrow might go through the tower and if the arrow is shot without any gravity it will look unrealistic.
Is there some sort of mathematical formula or does Unity provide any Method to calculate this? If someone can help I'll be very thankful. Sorry for my bad englisch.
Answer by Eno-Khaon · Mar 27, 2016 at 03:29 AM
I'm going to cheapskate this a little bit and refer you to a previous answer I've given. Your diagram and post don't explicitly state whether you're referring to a 2D or 3D game, so I'll simply offer two relevant links:
Here is my response to a question regarding 2D trajectory: http://answers.unity3d.com/questions/1124197/how-can-i-launch-a-gameobject-at-a-target-if-i-am.html
That also links to my main post relating to 3D trajectory: http://answers.unity3d.com/questions/1087568/3d-trajectory-prediction.html#answer-1087707
By your description, you would be able to base it on my second (3D) example of:
A -> B, attempting to arrive based on a specified launch angle
Thanks for all the answers. Eno $$anonymous$$haon anwer worked. The reason I needed so long is that I had a lot of stress in school and I wanted to find out, how Eno $$anonymous$$haon came to this formula. So I tried to recreate to formula with the Free Fall and the Throw. In case anyone wants to know how I calculated it, I'll attach some scans. The problem with my formula is, that it isn't the same, maybe someone knows, where my calculations are wrong. In case anyone is wondering, it is written German.
So again, thanks for all the anwers.
Answer by fideltfg · Mar 27, 2016 at 01:59 PM
I use this, found it myself a while back, but works for most cases where you need to hit a moving target from a static one.
Rather then calculating the speed the round needs to go it calculates a new aim point given the targets speed, distance and the known speed the round will travel. if you adjust the speed of the round then it will be more unrealistic then not using gravity. You will have to test a bit to get the correct speed for your rounds, to simulate the effects you want, but then run through his and you should get what your after.
It does add a 'tilt' to the projectile, but you can adjust the spawn point to avoid it spawning within the weapon itself. And of cause this only works to launch the round at the target. if the target seeds up or changes direction the round will miss.
use it like this
void Update(){
transform.LookAt(CalculateLead(target, weapon.transform, speed))
transform.forward = GetComponent<Rigidbody>().velocity;
}
public static Vector3 CalculateLead(GameObject target, Transform t, float speed)
{
Vector3 V = target.GetComponent<Rigidbody>().velocity;
Vector3 D = target.transform.position - t.position;
float A = V.sqrMagnitude - (speed * speed);
float B = 2 * Vector3.Dot(D, V);
float C = D.sqrMagnitude;
if (A >= 0)
{
Debug.LogError("No solution exists");
return target.transform.position;
}
else {
float rt = Mathf.Sqrt(B * B - 4 * A * C);
float dt1 = (-B + rt) / (2 * A);
float dt2 = (-B - rt) / (2 * A);
float dt = (dt1 < 0 ? dt2 : dt1);
return target.transform.position + (V * dt);
}
}
Answer by DesignPie · Mar 27, 2016 at 02:03 PM
Unity does have a good way to calculate such physics. Presuming that you are new to Unity, Unity has a neat script called a 'Collider'. Go into your project, locate the inspector, click 'Add Component', and then search 'collider' and select your desired shape for your collider (there're tons!).
Add a collider script to both your arrow prefab and your enemy prefab.
Assuming that you want your arrow to be affected by physics, add the 'Rigidbody' script to it.
To test it's velocity, you must use the OnCollisionEnter function coupled with some code, it will look somewhat like this;
void OnCollisionEnter(Collision collision) {
if (collision.relativeVelocity.sqrMagnitude > 2)
//Executes code if squared velocity is more than 2
}
Here, you are using the OnCollosionEnter function (broadcasted once your collider hits something) which returns a Collision (in this case, we name it collision). Then we check the collision's relative velocity (a Vector 3) and then we simply get it's squared Magnitude (the sqrt function is quite memory-expensive) and compare it to two or whatever you like. For me, I just play around with the limit variable until I find out it's perfect.
Hopefully that helps and good luck with your game ;)