Reliable Double Jump?

So, In my game, players can double jump by pressing jump once, then another jump in mid air. This works perfectly fine though there were some problems.

The first double jump script I used was the one provided by the roblox developer hub: https://developer.roblox.com/en-us/articles/Double-Jumping, I knew how it worked though, when the player jumps, then is in freefall, and the player decides to press the space key again, it fires the jump event again causing the player to essentially double jump in mid air. Theres also a debounce on it to make it only work once then have to be reinstated by landing on the ground. Though thats where the problem arises.

My game has many jumps and slopes. When the player happens to fall just a little after running up a slope or jumping right in between two parts, if the player decides to jump, it automatically does a double jump causing the player to get frustrated when they realize they cant double jump since it just broke.

So I decided to see if there was an alternative, there was one:

local UserInputService = game:GetService("UserInputService")
local character = script.Parent
 
local humanoid = character:WaitForChild("Humanoid")
 
local doubleJumpEnabled = false 
 
humanoid.StateChanged:Connect(function(oldState, newState)
 if newState == Enum.HumanoidStateType.Jumping then
  if not doubleJumpEnabled then 
   wait(.2)
   if humanoid:GetState() == Enum.HumanoidStateType.Freefall then
    doubleJumpEnabled = true 
   end
  end
 elseif newState == Enum.HumanoidStateType.Landed then 
  doubleJumpEnabled = false
 end
end)
 
UserInputService.InputBegan:Connect(function(inputObject)
 if inputObject.KeyCode == Enum.KeyCode.Space then
  if doubleJumpEnabled then
   if humanoid:GetState() ~= Enum.HumanoidStateType.Jumping then
    humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
    spawn(function()
     doubleJumpEnabled = false 
    end)
   end
  end  
 end
end)

Essentially how this code worked was by detecting if the player jumped, if they did, then double jump is enabled while in freefall, during that time, if the player decides to want to double jump, the part below detects when the player presses the SpaceBar (Important later on). Which works perfectly and makes doublejumpenabled = false when the player lands which fixed the problem that was ontop. But then I run into another issue, I realize that mobile players cant double jump since it only detects if someone presses the spacebar. I tried searching online for a way to track if the player presses the jump button on mobile but couldn’t find an answer.

Is there a way I could make a more reliable double jump system or a way to detect if a mobile player presses the jump button?

10 Likes

You would have to edit things with the default Control Script, and enable double jumps from there.

I haven’t checked if this will work

1 Like

Try UserInputService.JumpRequest. You should be able to use it like this:

game:GetService("UserInputService").JumpRequest:Connect(function()
 	print("The player sent a jump request")
end)

Since the wiki is down, I found this code here: How To BindAction To The Mobile Jump Button. The SetState stuff isn’t relevant here.

10 Likes

When I attempted to do that before, this problem occured:

EDIT: After re-working the code above and adding another debounce, I was able to get it to work correctly.
Thanks @iGottic for the hint about the performance cost btw, will keep that in mind.

You need a debounce system with that, or an “event pausing” loop.

Jump Request is also good in the sense that it has cross-platform support, even with modded controls or Xbox button binds.
However, it comes with a slight performance cost. No visible frame rate drop on its own, but does give enough errors (with inproper usage) to basically drop a bomb on studio.

EDIT: I use Jump Request for double jump on No Scope Sniping (https://www.roblox.com/games/1833791864/No-Scope-Sniping) it works fine with every player.

2 Likes

I might have a function that can help with this!
Here is how I get if a player Taps 2,3,4 and so on times, within a time limit.
(If that makes sense?)

   Jumping = {
JumpTick = 0,
Jumps = 0,
JumpTime = 0.25,
JumpsRequired = 2
}

game.Players.LocalPlayer:GetMouse().KeyDown:connect(function(key)
local ByteKey = string.byte(key)
	if key == " " then
	    if (tick() - Jumping.JumpTick) <= Jumping.JumpTime or Jumping.JumpTick == 0 then
			Jumping.JumpTick = tick()
			Jumping.Jumps = Jumping.Jumps + 1
			if Jumping.Jumps >= Jumping.JumpsRequired then
							
				Jumping.JumpTick = 0
				Jumping.Jumps = 0
	                                        -- The Player Has Made the Defined Jumps!
	        end
		else
			Jumping.JumpTick = tick()
			Jumping.Jumps = 1
		end
	end
end)

Note: mouse.KeyDown is depreciated, I recommend using ContextActionService. (This is kind of a old function I made a while ago, so I haven’t really updated it. Lol.)
You can also bind this with ANY key (which is useful for cross-platform)
The settings above will fire the function is the player jumps Two times in 0.25 seconds, this can be changed of course.

6 Likes