Calculating maximum player jump distance

I’m procedurally generating platforms for a platformer game.

They are randomized both in size and distance but I need to limit the maximum distance from one platform to the other. This is easy if your player speed is static, as even Studio calculates the maximum player jump distance in the Game Options window and you could easily manually calculate your value from there.

However, I want to speed up my player over time. This means I would need to use some math/physics to calculate the maximum jump distance as I change the player speed.

I’ve searched all over the web but there doesn’t seem to be a go to solution as this probably depends on the way the game engine calculates it’s physics for the player jumping. However there must be a formula and the proof to that is the editor being able to calculate the distance.

TL;DR I need a mathematical formula to calculate maximum player jump distance.

7 Likes

Hey check out this post which could probably help! The solution of the post is saying to use the script;

JumpPower^2 = 2 * workspace.Gravity * height

height = JumpPower^2 / (2*workspace.Gravity)
10 Likes

This seems like an interesting solution however this calculates the height of a jump? This doesn’t account for movement speed so it’s only halfway there I guess.

Presumably the math would at least need to take into account the gravity, the power of the jump and the speed of the player?

So you also are looking for something that can calculate the speed of the player based as well, or am I misunderstanding?

No, I need to calculate the maximum distance of the player’s jump. What is the furthest point you could reach by jumping/furthest distance. All I’m saying is it obviously needs to take into account the speed of a player to calculate the distance. As without that you are only calculating the maximum height of the jump.

If I understand correctly you want to calculate the horizontal distance of the jump.
This sounds like a kinematics problem. With the equation @ScytheSlayin had you can estimate the jump height, and you could probably use that to calculate the time the player will spend in the air, which multiplied by the player’s horizontal speed should give you the horizontal distance traveled during the jump.

2 Likes

Possibly, I’ll need to give this a go. If the numbers match up with what studio says then I’ll know the math is right.

Well I’m not really a maths guy so I can’t seem to figure out this formula on my own. I’ve got something set up but it’s definitely not correct.

The logic I’ve got in mind now would be: Get the amount of time the player can stay in the air by jumping and multiply that by the player speed as you have said.

I did some internet browsing and old highschool notebook reading to try to figure this out.

So we got the maximum height from an earlier reply:

h = (JumpPower ^ 2) / (2 * workspace.Gravity)

Maximum height can be calculated from initial velocity so we invert that to get the vertical component of our v0:

h = (v0 ^ 2) / (2 * workspace.Gravity)
v0 = math.sqrt(h * 2 * workspace.Gravity)

With initial velocity we can get the flight time:

t = (2 * v0) / workspace.Gravity

Multiplied by the horizonal velocity (which we’ll assume is constant) we get the range of the jump:

d = t * humanoid.WalkSpeed

There’s stuff that cancels out here, I’ll edit this more when I get home from work in a few minutes.

7 Likes

I’m not sure this equation is actually correct, at least not according to the reproducible test I just carried out. This equation gives h = 6.371050048129 as a result of the default 50 JumpPower.

Using this to test:

local runServ = game:GetService("RunService")

local char = script.Parent
local hum = char:WaitForChild("Humanoid")
local humRoot = char:WaitForChild("HumanoidRootPart")

repeat
	runServ.RenderStepped:Wait()
until humRoot.Velocity.Magnitude == 0

local low = humRoot.Position.Y
local high = low
print("Initial height: "..low)

local logger
logger = runServ.RenderStepped:Connect(function()
	local current = humRoot.Position.Y
	if current > high then
		high = current
	end
end)

hum.Jump = true

repeat
	runServ.RenderStepped:Wait()
until humRoot.Velocity.Magnitude == 0

logger:Disconnect()
print("Max height: "..high)
print("Max displacement: "..(high-low))

I found that I actually got the output as:

Initial height: 3
Max height: 10.26632976532
Max displacement: 7.2663297653198

NOTE: This test was carried out using R6, but displacement results were consistent regardless of avatar type and scale. Avatar type and scale only affected initial, and maximum height (but both by the same amount).

I’m not sure of the actual equation to calculate maximum displacement when given a jump power value, hopefully someone can share it with us though.

@buildthomas Seeing as you gave the equation that’s been used previously, would you happen to know if it was incorrect - and if so, what the correct eqation is?

Aha! Thank you for your effort really and it seems to be working! I got a result of 38 and studio’s estimate is 40. :smiley:

There is probably something we’re not accounting for but it doesn’t seem to be too significant and it’s fine that the distance is smaller than larger. Since that means the player will still be able to reach that point!

Here is the final code. I did some substitutions to cancel out values and got this:

d =  2 * humanoid.JumpPower * humanoid.WalkSpeed / workspace.Gravity

With everything cancelled out it turns out that JumpPower is actually the vertical velocity your character jumps with.

@UsernameMissingOrNil The calculations all put together seemed to work for me:

5 Likes

Hmm yes. Seems to be working just fine. There is a tiny margin of error as I mentioned before?

It’s always off by a certain number which doesn’t change unless I change the walkSpeed but changing gravity or jumpPower makes that innacuracity change values.

For example, instead of 40 as studio assumes i got 38. I upped the player speed and i got 43 instead of 45. I changed the gravity or jump power, and that number changed to a difference that is not two. Which means there is a flaw with calculating the height of the jump/air time.

This is really odd, as when I use your equation for default values of walk speed and jump power, I get d = 8.1549440616051. But, when I’ve tried jumping from evenly spaced platforms at this distance, I go further than predicted.

I used this to test:

local runServ = game:GetService("RunService")

local char = script.Parent
local hum = char:WaitForChild("Humanoid")
local humRoot = char:WaitForChild("HumanoidRootPart")

humRoot.CFrame = CFrame.new(0, 3, 0)

repeat
	runServ.RenderStepped:Wait()
until humRoot.Velocity.Magnitude == 0

hum:MoveTo(Vector3.new(0, 3, 100))
wait(1)

hum.Jump = true
local initialPos = humRoot.Position*Vector3.new(1, 0, 1)

wait()

local logger
logger = runServ.RenderStepped:Connect(function()
	if math.abs(humRoot.Velocity.Y) == 0 then
		local endPos = humRoot.Position*Vector3.new(1, 0, 1)
		print((initialPos-endPos).Magnitude)
		logger:Disconnect()
	end
end)

which gave me an output of 9.6001214981079. This value seemed to be exact, though I’m sure it’s slightly off.

Yes, the equations are all assuming constant velocity, and zero acceleration across the X and Z axes.

This all leads me to the question: what’s the real equation? I don’t know if there’s a known value of walk speed acceleration, but we definitely do accelerate - and it’s much clearer at higher speeds. Even at the default speed there is some noticeable acceleration over the space of a few frames:

-- New line = magnitude of velocity at each frame
  0
  7.9660329818726
  15.932065963745
  16
--output omitted (lots of 16 spam)
  8.0339670181274
  0.06793412566185
  0

But what is the value of the acceleration and deceleration?!

If you run the test again on multiple speeds, but also print DeltaTime, we might actually be able to figure acceleration out by graphing those magnitudes over time.

2 Likes

Well I guess we’ve got kind of a solution. I’ll keep on trying to figure something out, and if I stumble upon any new discoveries I’ll post them here!

2 Likes