How can I improve my "Three-Jump" script?

How can I improve my “Three-Jump” script?

I’m not happy about all the if and elseif statements, it doesn’t really look clean. Is there a way to get rid of them?

--Local Script (StarterPlayerScripts)


local UIS = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local char = player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local firstJump = false
local secondJump = false
local thirdJump = false

local ResetTime = 5



function ResetJumps()
	if firstJump == true and secondJump == true and thirdJump == true then
		wait(ResetTime)
		firstJump = false
		secondJump = false
		thirdJump = false
	end
end


UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.Space then
		if firstJump == false and secondJump == false and thirdJump == false then
			hum:ChangeState(Enum.HumanoidStateType.Jumping)
			firstJump = true
			
			elseif firstJump == true and secondJump == false and thirdJump == false then
			hum:ChangeState(Enum.HumanoidStateType.Jumping)
			secondJump = true
			
			elseif firstJump == true and secondJump == true and thirdJump == false then
			hum:ChangeState(Enum.HumanoidStateType.Jumping)
			thirdJump = true
			
			elseif firstJump == true and secondJump == true and thirdJump == true then
			
			
	
	              ResetJumps()
			
		end
	end
end)

1 Like

Hey there! I’ve created a little something inspired from your snippet here and just finished testing it. The following is intended to be a LocalScript under StarterCharacterScripts in StarterPlayer:

local UserInputService = game:GetService("UserInputService");

local character = script.Parent;
local humanoid = character:WaitForChild("Humanoid");

local canJump = true;
local currentJump = 0;

local CHECK_DELAY_IN_SECONDS = 0.2;
local MAX_JUMPS = 3;

--- An event listener for Humanoid.StateChanged that manages if and when a
--- Player's character can achieve more than one consecutive jump.
--- @param _ HumanoidStateType (just in case)
--- @param newState HumanoidStateType
--- @return nil
local function manageConsecutiveJumps(_, newState)
    if newState == Enum.HumanoidStateType.Jumping then
		canJump = false;
		wait(CHECK_DELAY_IN_SECONDS);
        currentJump = currentJump + 1;
		canJump = currentJump < MAX_JUMPS;
    elseif newState == Enum.HumanoidStateType.Landed then
        currentJump = 0;
		canJump = true;
	end
end

--- An event listener for UserInputService.InputBegan that dispatches the jump
--- input to the character when appropriate.
--- @param inputObject InputObject
--- @return nil
local function dispatchConsecutiveJumps(inputObject)
    local shouldDispatch = (
        inputObject.KeyCode == Enum.KeyCode.Space
		and humanoid:GetState() ~= Enum.HumanoidStateType.Jumping
        and canJump
    );

    if shouldDispatch then
        humanoid:ChangeState(Enum.HumanoidStateType.Jumping);
    end
end

humanoid.StateChanged:Connect(manageConsecutiveJumps);
UserInputService.InputBegan:Connect(dispatchConsecutiveJumps);

As always, if you have any questions on how something functions or why, let me know!

3 Likes

Thank you, it helped me. What do the ’ ; 's mean though? I personally never use them.

Semicolons are just a way to optionally end statements. While they are just that, optional, I urge others to use them to prevent some debugging issues that arise when you intend a statement to end but the compiler doesn’t infer it properly; it also tends to make tooling more consistent outside the realm of Roblox.

But if you don’t use them, it’s certainly not a crime, lol.

2 Likes

A little add-on to the solution,

Since it does not work on mobile I have modified the code of TheEdgyDevs and put this:

local UserInputService = game:GetService("UserInputService");

local character = script.Parent;
local humanoid = character:WaitForChild("Humanoid");

local canJump = true;
local currentJump = 0;

local CHECK_DELAY_IN_SECONDS = 0.25;
local MAX_JUMPS = 8;

--- An event listener for Humanoid.StateChanged that manages if and when a
--- Player's character can achieve more than one consecutive jump.
--- @param _ HumanoidStateType (just in case)
--- @param newState HumanoidStateType
--- @return nil
local function manageConsecutiveJumps(_, newState)
	if newState == Enum.HumanoidStateType.Jumping then
		canJump = false;
		wait(CHECK_DELAY_IN_SECONDS);
		currentJump = currentJump + 1;
		canJump = currentJump < MAX_JUMPS;
	elseif newState == Enum.HumanoidStateType.Landed then
		currentJump = 0;
		canJump = true;
	end
end

--- An event listener for UserInputService.InputBegan that dispatches the jump
--- input to the character when appropriate.
--- @param inputObject InputObject
--- @return nil
local function dispatchConsecutiveJumps()
	-- shouldDispatch considers if plr should jump or not ( .InputBegan has params, whilst JumpRequest does not.
	local shouldDispatch = (
			humanoid:GetState() ~= Enum.HumanoidStateType.Jumping
			and canJump
	);

	if shouldDispatch then
		humanoid:ChangeState(Enum.HumanoidStateType.Jumping);
	end
end

humanoid.StateChanged:Connect(manageConsecutiveJumps);
UserInputService.JumpRequest:Connect(dispatchConsecutiveJumps);