- Home /
Unity Messing up Basic Math? Projectile Trajectory Algorythm
Hello all, I am using the following equation from Wikipedia:
to calculate the required angle of my projectile to reach a point projected to 3D space from the cursor. I'm sure this would be working perfectly if Unity didn't keep seemingly messing up the math.
The following is an example script, what it gets, and what I get (from my head and a TI 83 calculator):
var x = 5; // x = 5 Distance to target
var v = grenadeForce; // v = 500 Projectile speed
var g = Physics.gravity.y; // g = -9.81 Gravity
//Debug.Log(g);
var gx2 = g * (x*x); // Unity and I both get -245.25
//Debug.Log(gx2);
var yv2 = 2 * 0 * (v*v); // Unity and I both get 0
//Debug.Log(yv2);
var inPar = gx2 + yv2; // Unity and I both get -245.25
//Debug.Log(inPar);
var minus = g * inPar; // Unity and I both get 2405.903
//Debug.Log(minus);
var sqrt = (v*v*v*v) - minus; //I get 6.249999759e10
Debug.Log(sqrt); //Unity gets -1.924512e9
Why is it that I get 6.24... for the pre-sqrt-ed number, but Unity is getting something completely different? In fact, it's so different, the complete function can't even return a real angle to fire with.
$$anonymous$$uch thanks. I just used $$anonymous$$athf.Pow since that returns a float, and now it matches, but now for some reason, the only two angles this returns is 89 and 1. Is it possible that Unity's physics don't mimic real life enough to use this formula? $$anonymous$$ore of the script in case I screwed it up:
function CalculateFiringAngle(target : Vector3, position : Vector3) {
var targetTransform = target;
var barrelTransform = position;
targetTransform.y = barrelTransform.y = 0;
var x = Vector3.Distance(targetTransform, barrelTransform); // x = 5 Distance to target
var v = grenadeForce; // v = 500 Projectile speed
var g = Physics.gravity.y; // g = -9.81 Gravity
//Debug.Log(g);
var gx2 = g * (x*x); // Unity and I both get -245.25
//Debug.Log(gx2);
var yv2 = 2 * 0 * (v*v); // Unity and I both get 0
//Debug.Log(yv2);
var inPar = gx2 + yv2; // Unity and I both get -245.25
//Debug.Log(inPar);
var $$anonymous$$us = g * inPar; // Unity and I both get 2405.903
//Debug.Log($$anonymous$$us);
var sqrt = (($$anonymous$$athf.Pow(v, 4)) - $$anonymous$$us); //I get 6.249999759e10
//Debug.Log(sqrt); //Unity gets -1.924512e9
if (sqrt < 0) {
//Debug.Log("No Solution");
return 0;
}
sqrt = $$anonymous$$athf.Sqrt(sqrt);
//Debug.Log(sqrt);
var calculatedAnglePos = $$anonymous$$athf.Atan(((v*v) + sqrt) / (g*x));
var calculatedAngleNeg = $$anonymous$$athf.Atan(((v*v) - sqrt) / (g*x));
return calculatedAnglePos * $$anonymous$$athf.Rad2Deg;
}
You might update or edit your original question ins$$anonymous$$d of posting a new question as an answer; but I don't think there's anything wrong : trajectories will have two answers in general above and below 45 degrees, so 89 (nearly straight up) and 1 (just above horizontal so that it immediately hits ground) seem to agree with your conditions of 500 (very fast) and 5 (don't go very far). If you want your projectile to start from above ground, or not be in a flat plane of insta-stop material, then you need a better model / equation. In other words, what numbers are you expecting here?
Apologies, first time on Answers. Believe it or not, 500 isn't all that fast. And 5 is actually a decent distance from my model, being only ~1 in size. I am of course using rigidbody.AddForce(direction * force). Oh, and the 89 answer literally goes above my model's head and straight back through it, there is next to no lateral movement. Is it possible that rigid body force is not the same as real world velocity? Or do you think my scale is so small the gravity is off?
To me it looks like, beside your "int" problem, that you messed up two different things here: Force and Velocity are two different things. 500 as a force isn't that much but it depends on how you use it and in what velocity it results. It you want a one time impulse when launching, make sure you use Force$$anonymous$$ode.VelocityChange. All other modes don't give you the right value since they either are taking the mass into account or are designed to apply the force over multiple frames, so it adds up to your desired value over a time of one second.
500 u/sec IS a very fast velocity. It will travel the distance of 5u in 0.01 sec or 10ms
Ah... So you suggest that changing the Force$$anonymous$$ode will allow my force to become my velocity? Or should I find some number to decide my force by and feed that to my algorithm?
Answer by hatshapedhat · Apr 14, 2013 at 07:13 PM
Probably an overflow. If grenade force "looks" like an integer, it's possible that the actual type of v
is a 32 bit integer, which if you take that to the fourth power, is larger than 2^31. Try and set v to 500.0
instead and see if the numbers match.
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Setting limits to my trajectory 2 Answers
Trajectory Projectile with Collision Detection 2 Answers
Ball Isn't following Trajectory line : Unity3d 1 Answer
Make character walk on walls defying gravity in a 2D Game 1 Answer