Issues in with my script for holding space for a higher jump and tapping it for a low jump

  • I want to achieve this: When the player holds down the spacebar it will make the jump higher, but if they tap it, they won’t go as high if they were to hold the spacebar

  • The issue is that the timer is going above the value I want it to be and when I tap the spacebar it doesn’t jump, I think I need to make adjustments to b:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)

  • I was browsing so much on the dev hub looking for the solution, it fixed most of the issues for the jumping, I just need it to work when tapping it lightly and I want the loop for the jumppower to not go above 30 so players don’t jump too high

Basically tapping for a low jump and holding it for a higher jump

local UserInputService = game:GetService("UserInputService")
local a = game.Players.LocalPlayer.Character
local b = a:FindFirstChild("Humanoid")
local notJumping = b.Jump == false
local isJumping = b.Jump == true

b:SetStateEnabled(Enum.HumanoidStateType.Jumping, false) print("canT jump bro")

UserInputService.InputBegan:Connect(function(inputObject, gameProcessed)
	if gameProcessed then return end
	wait(0.2)
	if inputObject.KeyCode == Enum.KeyCode.Space then 
		b:SetStateEnabled(Enum.HumanoidStateType.Jumping, false) print("cant jump bro")
		while wait(0) do
			b.JumpPower = b.JumpPower + 1 
			if b.JumpPower == 30 then break 
			end 
		end
			UserInputService.InputEnded:Connect(function(inputObject, gameProcessed) 
				if gameProcessed then return end
				
					if inputObject.KeyCode == Enum.KeyCode.Space then print("Player has stopped holding down spacebar")
				b:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)print("can jump")
					wait(0.1)
					b.WalkSpeed = 13
					b.Jump = true
					if Enum.HumanoidStateType.Jumping == false then
			wait(1)
					b:GetState() if Enum.HumanoidStateType.Jumping == false then
						wait(0.2)
						b:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)print("bruh")
							b.WalkSpeed = 16
							b.JumpPower = 0
							
					end
			end
	end
	end)
	end
	end)
1 Like

Have you looked at iskeydown as method to determine if space is being held?

Trying to follow the logic of your code, it’s not really clear how it’s supposed to accomplish what you want. Part of your issue might be this:

b.JumpPower = b.JumpPower + 1 
if b.JumpPower == 30 then --Dependent on JumpPower always being an int, e.g. 29.5 + 1 ~= 30, so continues FOREVER. Use >= instead?
	break 
end 

Another part might be that you never disconnect the connection for InputEnded, which is set up every time space is pressed. The 100th time you release space, it’s going to check 100 times if it’s the space bar and do all that stuff 100 times.

Instead of using waits to set the jump power depending on how long has passed, I’d calculate it when it’s relevant and use the actual number to scale the jump height. Something like this (put in StarterCharacter):


local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local character = game.Players.LocalPlayer.Character
local humanoid = character:FindFirstChild("Humanoid")

local jumpKey = Enum.KeyCode.Space
local jumpPowerMin = 40
local jumpPowerMax = 100

local jumpChargeMaxSeconds = 0.5

local function lerp(fraction, rangeStart, rangeEnd)
  --Linear interpolation
  --Returns a value that is (fraction) of the way from rangeStart to rangeEnd.
  --Given a fraction in [0, 1], returns a value in [rangeStart, rangeEnd].
  return rangeStart + (rangeEnd - rangeStart) * fraction
end

local function invLerp(value, rangeStart, rangeEnd)
  --Inverse linear interpolation
  --Returns the fraction of the way that value is from rangeStart to rangeEnd.
  --Given a value in [rangeStart, rangeEnd], returns a fraction in [0, 1].
  return (value - rangeStart)/(rangeEnd - rangeStart)
end

local function mapRange(value, fromRangeStart, fromRangeEnd, toRangeStart, toRangeEnd)
  --Returns a value mapped from one number range to another
  return lerp( 
    invLerp(value, fromRangeStart, fromRangeEnd), 
    toRangeStart, 
    toRangeEnd 
  )
end

--Disable normal jumping. State is re-enabled when we want character to jump.
humanoid:SetStateEnabled("Jumping", false)

UserInputService.InputBegan:Connect(function(startedInput, eventProcessed)
  if eventProcessed then return end
  
  if startedInput.KeyCode == jumpKey then
    --Store the time that we started pressing jump key
    local jumpChargeStartT = tick()
    
    local inputEndedC
    inputEndedC = UserInputService.InputEnded:Connect(function(endedInput, eventProcessed)
      if eventProcessed then return end
      
      if endedInput.KeyCode == jumpKey then
        --Cleanup InputEnded connection
        inputEndedC:Disconnect()
        
        --Calculate time since we started pressing jump key
        local jumpChargeSeconds = tick() - jumpChargeStartT
        
        --Limit the jump power
        jumpChargeSeconds = math.min(jumpChargeSeconds, jumpChargeMaxSeconds)
        
        --Calculate the jump power
        local jumpPower = mapRange(
          jumpChargeSeconds, --value
          0, jumpChargeMaxSeconds, --from range
          jumpPowerMin, jumpPowerMax --to range
        )
        
        print(string.format("%3.2f s => %3.2f JP", jumpChargeSeconds, jumpPower))
        
        humanoid:SetStateEnabled("Jumping", true)
        humanoid.JumpPower = jumpPower        
        
        --Wait a frame before jumping, because apparently SetStateEnabled doesn't take effect until then
        RunService.RenderStepped:Wait()
        humanoid.Jump = true
        
        --Wait a frame before disabling jumpng, because apparently SetStateEnabled DOES stop the jump before it can happen
        --  if we don't.
        RunService.Stepped:Wait()
        humanoid:SetStateEnabled("Jumping", false)
      end
    end)
  end
end)

This “charges up” the jump before it happens. If you want to jump right away, there’s no way to control the jump height by changing the initial impulse during the jump - because the impulse was already applied. Instead you’ll have to have an upwards force that effectively makes gravity less powerful during the jump, which is removed as soon as the jump key is released. You can also play with making gravity stronger than normal after the jump key is released, to get some interesting jump curves.

If you google jump curves in game design, there’s a couple good videos on YT.

6 Likes

Ay, thanks man, I got what I wanted, basically the closest to it. Thanks for the feedback and this is actually my first userinput script, hopefully I can learn from my mistakes so that next time I will do better, thanks.

2 Likes

I was trying to make a similar system but this solution works better.