# Physics trajectory help...

This is a problem I’ve been trying to figure out for some time and I really want to figure out the formula for this. I’m definitely weak at coding when it has to do with physics calculations. Anyway, the problem is I want to be able to point at a spot in 3D space and calculate the necessary force/trajectory to shoot a rigid body object that will land at that exact point.

There’s 2 ways to do this… calculate the necessary force to shoot the rigid body to the point on a straight line (increasing force to some amount), or shoot the rigid body at a force plus an angle to reach the hit point on an arc (I’d prefer this solution). Any help is much appreciated, a solution to this would open up a lot of gameplay ideas I have.

My code so far (which is admittedly horrible)…

``````var flashGrenade : GameObject;
var hit : RaycastHit;
var shooter : Transform;

var crossHair : GameObject;

function Start ()
{
Screen.showCursor = false;
}

function Update ()
{
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);

if (Physics.Raycast (ray, hit))
{
crossHair.transform.rotation = Quaternion.FromToRotation (Vector3.up, hit.normal);
crossHair.transform.position = hit.point + (hit.normal * 0.03);

if (Input.GetMouseButtonDown (0))
{

theDistance = Vector3.Distance (hit.point, shooter.position);

thrownGrenade.rigidbody.AddForce (transform.TransformDirection (hit.point + Vector3 (0,Mathf.Abs (hit.point.y - shooter.position.y), 0)  - shooter.position) * (theDistance * 9.86));

}
}

else
{
crossHair.transform.position = Vector3.zero;
}
}
``````

Wow, my physics has gotten very rusty. I’ve been scribbling equations for a few minutes and haven’t come up with anything yet (aside from dead ends).

Perhaps these resources will be helpful to you: Trajectories College Board - SAT, AP, College Search and Admission Tools

I’ll probably look at this again tomorrow. Please post if you figure it out.

I realized why I hadn’t come to a solution earlier: there are too many variables. There’s literally an infinite amount of solutions to reach the goal.

In order to solve this, you will need to choose something to fill in one of your variables: time (of the trajectory), velocity, or angle. Is there anything in particular you would like to go with?

as it’s a grenade you want to throw then I would use time as the set variable. as all grenades have a time limit before they explode.

so you want to get to point x to y in set amount of time. plus if you have an obstacle to get over, that is another variable you can use to help solve the equation.

just my 2c… still don’t know how to solve your problem though!

cheers.

Think of the overground (X-Z axis) distance and height (Y axis) as two separate components. If your projectile’s speed is constant (ie, no air drag) then just divide the target distance by the overground velocity to get the amount of time the object must remain in the air (eg, 10 unit range, 5 unit/sec velocity gives 2 sec of flight).

As for the height, think of it as two separate phases, rising and falling, which each take up half of the overall travel time. You basically need to know how fast the projectile would be going after falling for half the travel time. Assuming your gravity is the standard 9.8 units/second, you just multiply half the travel time by 9.8 to get the Y axis component of the velocity at firing time.

Rather than worry about forces, I think you should just be able to set the velocity of the projectile directly using Rigidbody.velocity. Conveniently, the direction of the velocity vector is the direction in which the gun should be pointing.

Note that the forward speed of the projectile will not be exactly the same each time - not entirely realistic, but convincing and much easier than working out the firing angle for a known muzzle velocity. Also note that, like the others, my physics is a bit rusty too, so I apologise in advance if this method is dodgy. (I think it’s OK, though!)

Setting the velocity is definitely what I would suggest too.

As far as calculating the velocity based on time, I think the time should also be based on the distance of the target - it should take longer to hit a far target than a close one. I’ll see if I can write up a formula for you.

andeeee: I was assuming that the ground was not flat - therefore the halfway point (time-wise) wouldn’t necessarily be the apex of the projectile’s trajectory.

Let’s say that time is calculated based on the total of x, y, and z distance from the target.

``````t = Mathf.abs(hit.point.y - shooter.position.y) + Mathf.abs(hit.point.x - shooter.position.x) + Mathf.abs(hit.point.z - shooter.position.z);
``````

For now, we’ll treat x and z just as x. To get the x velocity, we use x = x0 + Vx*t, where Vx is the x velocity. Therefore:

``````velocity.x = (hit.point.x - shooter.position.x)/t;
``````

Next, we calculate the y velocity using y = y0 + V0yt + 1/2g*t^2, where V0y is the initial y velocity and g is gravity.

``````velocity.y = (hit.point.y - shooter.position.y)/t - Physics.gravity.y*/2*t;
``````

From there, split your velocity.x into x and z.

Thanks everyone for your feedback so far, I only have time to work on these diversions every once in a while

So I have to admit that I’m still a bit confused about this. Tonight I did some work… I have a normalized direction and distance to the hit point * a set velocity. These two variables should be enough to solve for Y right? I have the distance to the hit point on the XZ plane thanks to Pythagoras… so now all that needs to be figured out is the angle to arc the projectile along its course?

I’ve been combing this page up and down tonight trying to get a working formula and I might be close if I can figure out how to turn an angle back into a vector.

I tried tim’s ideas, but they just sent projectiles flying upwards to who knows where… it might be a solid solution but I can’t make it work. If tim could turn that into a working script I’m sure a lot of people would benefit (and of course I’d owe you one).

Anyway, here’s the equation I’m trying to turn into code:

Aside from other problems that may arise, odds are that the calculated t values are too high. What are you getting? t should represent how many seconds it takes for the projectile to hit its target.
Good call on using the Pythagorean theorem for the hit distance. What was I thinking? Don’t answer that.

Is the terrain flat?
Do you want there to be a maximum “power” of the shooter?

I’ll see if I can get something working in the next couple days when I have a chance. I probably will not be able to look at it tonight (it’s currently about 6:40 AM over here in Chicago).
If you’d like to upload what you have right now, that might be helpful. It can be stripped down to just the areas you’re concerned about.

If you are firing over flat land then my original suggestion would probably be OK (perhaps it’s best to start with flat terrain anyway and think about height later when it’s all working).

The code would look something like:-

``````const float fwdSpeed = 10f; // Or whatever...

Vector3 targetDisp = target.position - gun.position;
float targetDistance = targetDisp.magnitude;
Vector3 groundVelocity = targetDisp.normalize * fwdSpeed;

float flightTime = targetDistance / fwdSpeed;
float timeToMaxHeight = flightTime / 2;

Vector3 upwardVelocity = -Physics.gravity * timeToMaxHeight;

Vector3 overallVelocity = groundVelocity + upwardVelocity;
Vector3 gunDirection = overallVelocity.normalize;

// ...and then later, when it's time to fire...

projectile.rigidbody.velocity = overallVelocity;
``````

(The code can be much more condensed than this, of course - I was aiming for clarity.)

The idea with the upward velocity is that it will have slowed down to zero under gravity (ie, object will start falling) at exactly the halfway point of the flight.

Im having trouble with the ball not getting to the target it keeps going short. Unless i set the fwdSpeed up high then it just goes in a line.

Has anyone had luck getting this working? I’m still trying to get my ball going in the right place not sure just keep trying if I find anything I will let everyone know.

Edit: I got it working added to the z position. Then for the fwdSpeed I did the mag of the distance between both vectors then added a scale value. Thanks for everyones help.

``````	football.transform.parent = null;
football.collider.isTrigger = false;
football.rigidbody.useGravity = true;

var targetDisp = target - this.transform.position;
targetDisp.z += 0.5;
var targetDistance = targetDisp.magnitude;
var fwdSpeed = targetDistance * 1.7;
var groundVelocity = targetDisp.normalized * fwdSpeed;

var flightTime = targetDistance / fwdSpeed;
var timeToMaxHeight = flightTime / 2;

var upwardVelocity = -Physics.gravity * timeToMaxHeight;

var overallVelocity = groundVelocity + upwardVelocity;

football.rigidbody.velocity = overallVelocity;
``````