- Home /
Calculate AI jumping the gap
I'm trying to figure out a jump trajectory calculation for my AI. I found this video and thought that this is what I was looking for. It takes in account of the AI's max speed and jump height, plus its chooses out of 3 optimal arcs to go, the lowest and least obscured arc is the best. I somehow can't come up with a calculation for this. Anyone know how?
Answer by Eno-Khaon · Jun 08, 2015 at 07:01 PM
This is something I've been working at for a little while now, so here are my thoughts on this:
You're looking to determine whether the AI can successfully cross a gap by jumping. This makes the assumption that you already know the maximum height they're able to jump and the maximum speed they're able to run.
With that in mind, it means you can also make the determination based on whether the target can be reached at all.
First, you have jump height:
public static float CalculateJumpForce(float gravityStrength, float jumpHeight)
{
//h = v^2/2g
//2gh = v^2
//sqrt(2gh) = v
return Mathf.Sqrt(2 * gravityStrength * jumpHeight);
}
(Gravity strength in this case is the magnitude of the gravity vector pushing against you)
This determines how much force it will take to jump up a specified number of units into the air, based on jumpHeight. Using this, half of the equation is dealt with. You know how much upward force will be provided.
Horizontal speed is easy, because its calculation is linear: All that matters for it is the character's current horizontal speed. In this case, how fast they run is how fast they're going to the side. That's all there is to it.
Then, combine the two:
maximumJumpVelocity = CalculateJumpForce(Physics.gravity.magnitude, myJumpHeight) + maxRunSpeed;
Now you have your maximum jumping capability lined up. For the time being, I'll shorten "maximumJumpVelocity" down to "mJV".
With this, the final jump must be tested: Can the character even MAKE the jump?
Vector3 horizontalVector = jumpDest - jumpStart; // Where you're trying to reach and where you're jumping from to get there
float verticalDistance = horizontalVector.y; // Snag the vertical distance before flattening the vector on the Y-axis
horizontalVector.y = 0;
float horizontalDistance = horizontalVector.magnitude;
// With the vertical and horizontal properties of the trajectory separated out,
// It's time to actually determine whether the jump can be made.
// More efficient than Mathf.Pow(), since they're simple enough.
float x2 = horizontalDistance * horizontalDistance;
float v2 = launchSpeed * launchSpeed;
float v4 = launchSpeed * launchSpeed * launchSpeed * launchSpeed;
float gravMag = Physics.gravity.magnitude;
float leapTest = v4 - (gravMag * ((gravMag * x2) + (2 * verticalDistance * v2)));
if(leapTest < 0)
// Can't make the jump
Knowing this, it can also be extrapolated further: If the jump can be made, what angle should it be made at? Well, when you have a predetermined force, there are two different angles that can be applied to reach a destination. Which one to use is up to you, but when you have the data readily available, why not just calculate both at once?
Vector3[] leap = new Vector3[2]; // One high jump, one low jump
if(leapTest >= 0)
{
float[] tanAngle = new float[2];
tanAngle[0] = (v2 - Mathf.Sqrt(v4 - gravMag * ((gravMag * x2) + (2 * verticalDistance * v2)))) / (gravMag * horizontalDistance);
tanAngle[1] = (v2 + Mathf.Sqrt(v4 - gravMag * ((gravMag * x2) + (2 * verticalDistance * v2)))) / (gravMag * horizontalDistance);
float[] finalAngle = new float[2];
// Low Jump
finalAngle[0] = Mathf.Atan(tanAngle[0]);
// High Jump
finalAngle[1] = Mathf.Atan(tanAngle[1]);
leap[0] = (horizontal.normalized * launchSpeed * Mathf.Cos(finalAngle[0])) - (gravityBase.normalized * launchSpeed * Mathf.Sin(finalAngle[0]));
leap[1] = (horizontal.normalized * launchSpeed * Mathf.Cos(finalAngle[1])) - (gravityBase.normalized * launchSpeed * Mathf.Sin(finalAngle[1]));
}
return leap;
All of this combined will let you determine the maximum distance your character can jump (including jumping up/down from ledges, as far as why it's quite so involved). The only caveat with how I've specifically structured this is that it's based specifically on providing a set amount of force. That means that, while your character can know whether the jump can possibly be made, tilting the angle up or down will make your character jump slightly higher or faster than their maximums. Fine-tuning the process to suit your specific needs will require, well, fine tuning and a little extra research.