Help on making a reliable multiple-jump system?

I want to make a reliable multiple jump system that doesn’t sometimes fling the player like shown in the game Ninja Legends.

This is one of my first times with HumanoidStates and stuff so I do not understand it that much. This is what I was able to get (flinging not shown in video)
[https://i.gyazo.com/c01d8eaf78e7d98cd0810188f2497288.mp4] (I don’t know why video won’t embed.)

I have used the toolbox, developer hub and found nothing. I’ve been trying to make it so I can change the amount of jumps a player can do with a variable such as jumpAmounts = 3 or something like that.

Here is my code:

-- rewritten by recanman, original: developer.roblox.com
-- SETTINGS:
local id = 5083625719 -- put the animation id here
local beamLife = 1.7 -- how long in seconds the beam will last
local beamWidth = 1 -- how wide the beam is
local doubleJump_WalkSpeed = 500 -- how fast the player should go while double jumping
------------
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local UserInputService = game:GetService("UserInputService")
local localPlayer = game.Players.LocalPlayer
local character
local humanoid

local animObj = Instance.new("Animation")
animObj.AnimationId = "rbxassetid://" .. tostring(id)
 local anim = Humanoid:LoadAnimation(animObj)
local HumaoidRP = Character:WaitForChild("HumanoidRootPart")
local canDoubleJump = false
local hasDoubleJumped = false
local oldPower
local TIME_BETWEEN_JUMPS = 0.125
local DOUBLE_JUMP_POWER_MULTIPLIER = 4
 
local function addEffect(pName) 
	local att0 = script.ParentPart.att0:Clone()
	att0.Parent = character[pName]
	att0.Position = Vector3.new(0, 0, 0)
	att0.WorldPosition = character[pName].Position + Vector3.new(0, 0.1, 0)

	local att1 = script.ParentPart.att1:Clone()
	att1.Parent = character[pName]
	att1.Position = Vector3.new(0, 0, 0)
	att1.WorldPosition = character[pName].Position - Vector3.new(0, 0.1, 0)

	local trail = script.ParentPart.Trail:Clone()
	trail.Parent = character[pName]
	trail.Attachment0 = att0
	trail.Attachment1 = att1
	trail.MinLength = beamWidth

	local particle = script.ParentPart.ElectricityParticle:Clone()
	particle.Parent = character[pName]
	
	game:GetService("Debris"):AddItem(trail, beamLife)
	game:GetService("Debris"):AddItem(att0, beamLife)
	game:GetService("Debris"):AddItem(att1, beamLife)
	game:GetService("Debris"):AddItem(particle, beamLife)
end

function onJumpRequest()
	if not character or not humanoid or not character:IsDescendantOf(game.Workspace) or
	 humanoid:GetState() == Enum.HumanoidStateType.Dead then
		return
	end
 
	if canDoubleJump and not hasDoubleJumped then
		addEffect("LeftHand"); addEffect("RightHand")
		hasDoubleJumped = true
		humanoid.JumpPower = oldPower * DOUBLE_JUMP_POWER_MULTIPLIER;
		humanoid.WalkSpeed = doubleJump_WalkSpeed
		humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		wait()
		anim:Play()
		anim.Stopped:Connect(function() humanoid.WalkSpeed = 16 end)
	end
end
 
local function characterAdded(newCharacter)
	character = newCharacter
	humanoid = newCharacter:WaitForChild("Humanoid")
	hasDoubleJumped = false
	canDoubleJump = false
	oldPower = humanoid.JumpPower 
	humanoid.StateChanged:Connect(function(old, new)
		if new == Enum.HumanoidStateType.Landed then
			canDoubleJump = false
			hasDoubleJumped = false
			humanoid.JumpPower = oldPower
			elseif new == Enum.HumanoidStateType.Freefall then
				wait(TIME_BETWEEN_JUMPS)
				canDoubleJump = true
		end
	end)
end
 
if localPlayer.Character then
	characterAdded(localPlayer.Character)
end
 
localPlayer.CharacterAdded:Connect(characterAdded)
UserInputService.JumpRequest:Connect(onJumpRequest)

Put it in StarterPlayerScripts

Here is a place if you want to test it (there is a particle and stuff inside the script)
stuff.rbxl (21.8 KB)

btw there is a part with attachments and a particle and trail ill upload an rbxl file shortly

I am not very sure if I can help you with this link:

But at the bottom of the page is a code where is a duble jump script.
You can try it and mess around. I recommend you to read a bit what changestate, setstate, statetyp is :wink:

1 Like

I’ve tried that but it sometimes flings the character…
And how do I make it 3 jumps for example?

In the script is written this:

if humanoid:GetState() ~= Enum.HumanoidStateType.Jumping then
    humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
    spawn(function()
    doubleJumpEnabled = false 
end)

Add under humanoid:ChangeState(Enum.HumanoidStateType.Jumping) a wait() and put this line again. ok not a clever idea, but you can try it.
You can also try to put the statements for the second jump under the second jump for a third jump.
This means:
The scripts there works like this:
player jumps → player falls → script makes the player jump again(double jump) → player falls → script makes the player jump (third jump) → player falls.

For the second question:
What do you mean exactly with flings?
I am not very good in english and my translator doesn’t explain me it exactly. I watched also the video, but I did not really saw what you mean.
Do you mean with fling, that the player jumps stay a second in air and falls back down? If you mean this then it is from roblox. Not from the script that causes it.

1 Like

No no, the player falls on the ground and gets launched randomly.
I also would prefer if it were a variable that I could change.

if you’re trying to determine how much times a player can jump after their initial jump you’d do something like this

-- the max amount of times a player can jump after first leaping off of the ground
local MAX_JUMP_LIMIT = 3

-- the amount of times a player has jumped after their first jump
local currentJumps = 0
-- the magnitude of the velocity, aka how high the player will jump
local jumpPower = 50

InputService.InputBegan:Connect(function(key,GPS)
 if GPS then return end
-- detect input
 if key.KeyCode == Enum.KeyCode.Space then
-- check to see if the player is in the air
   if humanoid:GetState() == Enum.HumanoidStateType.Freefall then
     if currentJumps ~= MAX_JUMP_LIMIT then
      -- basically see the player's velocity, allowing them to jump
      -- additionally you can add your jump animation in here and whatever else
      humanoidRootPart.Velocity = humanoidRootPart.Velocity + (Vector3.new(0, 1, 0) * jumpPower)
      -- increment the amount of times we've jumped value
      currentJumps = currentJumps + 1
     end
   end
 end
end)

Humanoid.StateChanged:Connect(function(oldState, newState)
    if newState == Enum.HumanoidStateType.Landed then
     -- everytime the player lands we reset the amount of times they've jumped previously
     currentJumps = 0
   end
end)


I haven’t tested this but lmk If it works

1 Like

Syharaa responded, meanwhile I tested my edited script in studio. Here is my edited script if you still need it:

-- rewritten by recanman, original: developer.roblox.com
-- SETTINGS:
local id = 5083625719 -- put the animation id here
local beamLife = 1.7 -- how long in seconds the beam will last
local beamWidth = 1 -- how wide the beam is
local doubleJump_WalkSpeed = 500 -- how fast the player should go while double jumping
------------
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local UserInputService = game:GetService("UserInputService")
local localPlayer = game.Players.LocalPlayer
local character
local humanoid

local animObj = Instance.new("Animation")
animObj.AnimationId = "rbxassetid://" .. tostring(id)
 local anim = Humanoid:LoadAnimation(animObj)
local HumaoidRP = Character:WaitForChild("HumanoidRootPart")
local canDoubleJump = false
local hasDoubleJumped = false
local oldPower
local TIME_BETWEEN_JUMPS = 0.125
local DOUBLE_JUMP_POWER_MULTIPLIER = 4
 
local function addEffect(pName) 
	local att0 = script.ParentPart.att0:Clone()
	att0.Parent = character[pName]
	att0.Position = Vector3.new(0, 0, 0)
	att0.WorldPosition = character[pName].Position + Vector3.new(0, 0.1, 0)

	local att1 = script.ParentPart.att1:Clone()
	att1.Parent = character[pName]
	att1.Position = Vector3.new(0, 0, 0)
	att1.WorldPosition = character[pName].Position - Vector3.new(0, 0.1, 0)

	local trail = script.ParentPart.Trail:Clone()
	trail.Parent = character[pName]
	trail.Attachment0 = att0
	trail.Attachment1 = att1
	trail.MinLength = beamWidth

	local particle = script.ParentPart.ElectricityParticle:Clone()
	particle.Parent = character[pName]
	
	game:GetService("Debris"):AddItem(trail, beamLife)
	game:GetService("Debris"):AddItem(att0, beamLife)
	game:GetService("Debris"):AddItem(att1, beamLife)
	game:GetService("Debris"):AddItem(particle, beamLife)
end

function onJumpRequest()
	if not character or not humanoid or not character:IsDescendantOf(game.Workspace) or
	 humanoid:GetState() == Enum.HumanoidStateType.Dead then
		return
	end
 
	if canDoubleJump and not hasDoubleJumped then
		addEffect("LeftHand"); addEffect("RightHand")
		hasDoubleJumped = true
		humanoid.JumpPower = oldPower * DOUBLE_JUMP_POWER_MULTIPLIER;
		humanoid.WalkSpeed = doubleJump_WalkSpeed
		humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		wait()
		anim:Play()
		Humanoid.StateChanged:Connect(function(oldState, newState)
			if newState == Enum.HumanoidStateType.Landed then
				humanoid.WalkSpeed = 16
			end
		end)
	end
end
 
local function characterAdded(newCharacter)
	character = newCharacter
	humanoid = newCharacter:WaitForChild("Humanoid")
	hasDoubleJumped = false
	canDoubleJump = false
	oldPower = humanoid.JumpPower 
	humanoid.StateChanged:Connect(function(old, new)
		if new == Enum.HumanoidStateType.Landed then
			canDoubleJump = false
			hasDoubleJumped = false
			humanoid.JumpPower = oldPower
			elseif new == Enum.HumanoidStateType.Freefall then
				wait(TIME_BETWEEN_JUMPS)
				canDoubleJump = true
		end
	end)
end
 
if localPlayer.Character then
	characterAdded(localPlayer.Character)
end
 
localPlayer.CharacterAdded:Connect(characterAdded)
UserInputService.JumpRequest:Connect(onJumpRequest)

If you land, then you will no longer run so fast around. Because that was the problem I had when I tested it in ROBLOX Studio.

1 Like

It works!!! Animation works too!

Thank you so much for helping me.

1 Like