How to double jump in roblox arsenal

Double jumping is a feature that appears in many games. This tutorial will cover how to implement it in Roblox.

Setting Up

To get started, you will need to insert a LocalScript into StarterPlayerScripts. You can name it whatever you want, but you should name it something descriptive so you can find it quickly if you need to. In this tutorial, it will be named DoubleJump.

In this script, you will need to get the player’s character and that character’s humanoid. The humanoid is the controller inside the character model that allows it to move and jump.

local localPlayer = game.Players.LocalPlayer local character local humanoid local function characterAdded(newCharacter) character = newCharacter humanoid = newCharacter:WaitForChild("Humanoid") end if localPlayer.Character then characterAdded(localPlayer.Character) end localPlayer.CharacterAdded:connect(characterAdded)

The characterAdded function takes a character model as an argument and stores that character into the variable character. It also stores that character’s humanoid in the humanoid variable. You should use Instance/WaitForChild instead of simply accessing newCharacter.Humanoid, as when the character first loads it could take a bit of time for the humanoid to load.

The characterAdded function is bound to the player’s Player/CharacterAdded event. Binding to CharacterAdded makes sure that this function is called every time the player respawns. However, sometimes on game initialization this script will run after the first player is spawned. To cover this case, you also need to call characterAdded on the player’s character if it already exists.

To make the player’s character double jump, it is important to know how the default jump works. The humanoid instance which controls movement and jumping of characters has a built-in state machine that says how it should behave. When a player jumps, the state of their humanoid is set to Jumping, which applies an upwards force to the character model. A brief moment later, the humanoid is set to the Freefall state, which lets physics take over and pull the character back to the ground with gravity. When the character hits the ground again the state of the humanoid is set briefly to landed.

A simple way to implement double jump is to force the character back into the Jumping state. We can also listen to when the state changes back to Landed to prevent the character from double jumping more than once.

You can use Humanoid/ChangeState to force the character back into the jumping state in order to cause the double jump.

To make the player’s character double jump you will also need to know when the player pressed the jump input. To do this you can use an event of UserInputService called UserInputService/JumpRequest. This event is fired whenever the player tries to jump.

Listening to JumpRequest is recommended over listening to specific input from the player (such as when the player presses the spacebar). By default, JumpRequest fires whenever the input specific to the device is used. Listening to the event instead of explicit input will make your game cross-platform compatible.

Add the highlighted code to your script:

local UserInputService = game:GetService("UserInputService") local localPlayer = game.Players.LocalPlayer local character local humanoid local canDoubleJump = false local hasDoubleJumped = false function onJumpRequest() if not character or not humanoid or not character:IsDescendantOf(workspace) or humanoid:GetState() == Enum.HumanoidStateType.Dead then return end if canDoubleJump and not hasDoubleJumped then hasDoubleJumped = true humanoid:ChangeState(Enum.HumanoidStateType.Jumping) end end local function characterAdded(newCharacter) character = newCharacter humanoid = newCharacter:WaitForChild("Humanoid") humanoid.StateChanged:connect(function(old, new) if new == Enum.HumanoidStateType.Freefall then canDoubleJump = true end end) end if localPlayer.Character then characterAdded(localPlayer.Character) end localPlayer.CharacterAdded:connect(characterAdded) UserInputService.JumpRequest:connect(onJumpRequest)

JumpRequest is bound to the function onJumpRequest. This function first checks if these conditions are met:

  • The character and humanoid variables are not nil
  • The character is currently somewhere in the workspace
  • The character is currently spawned

If any of these are not fulfilled, the code stops executing by calling return. If all of them are, it moves on to the next statement. This is to prevent double jumping when there is no character.

A player can double jump if the Humanoid is currently in freefall and has not already double jumped. The first of these conditions can be checked with canDoubleJump which is set to true when the humanoid is in the Freefall state. The next condition, making sure the player hasn’t already done a double jump, can be handled with a technique called Debounce. In this case, the variable hasDoubledJumped is initially false but gets set to true as soon as the humanoid performs the double jump.

If the conditions are right for a double jump, you can call ChangeState to force the jump.

Resetting

Although the player can now double jump, there is still some cleanup to do. In your testing, you probably noticed that you can only double jump once; after that, you cannot do it again. This is a simple fix: when the player has landed, reset canDoubleJump and hasDoubleJumped to false.

local UserInputService = game:GetService("UserInputService") local localPlayer = game.Players.LocalPlayer local character local humanoid local canDoubleJump = false local hasDoubleJumped = false function onJumpRequest() if not character or not humanoid or not character:IsDescendantOf(workspace) or humanoid:GetState() == Enum.HumanoidStateType.Dead then return end if canDoubleJump and not hasDoubleJumped then hasDoubleJumped = true humanoid:ChangeState(Enum.HumanoidStateType.Jumping) end end local function characterAdded(newCharacter) character = newCharacter humanoid = newCharacter:WaitForChild("Humanoid") hasDoubleJumped = false canDoubleJump = false humanoid.StateChanged:connect(function(old, new) if new == Enum.HumanoidStateType.Freefall then canDoubleJump = true elseif new == Enum.HumanoidStateType.Landed then canDoubleJump = false hasDoubleJumped = false end end) end if localPlayer.Character then characterAdded(localPlayer.Character) end localPlayer.CharacterAdded:connect(characterAdded) UserInputService.JumpRequest:connect(onJumpRequest)

Tuning

If you test the code so far you may have noticed that if you hold the spacebar, the double jump looks more like a bigger jump than a second one. This is because Enum/HumanoidStateType/Freefall is set before the player starts to actually fall. To fix this, and make the double jump look more like a second jump, you should wait before setting canDoubleJump to true.

You can also make the second jump more pronounced by increasing the jump power for the second jump. You can set the force of the jump with Humanoid/JumpPower. Just be sure to reset JumpPower back to its initial value once the character has landed.

local UserInputService = game:GetService("UserInputService") local localPlayer = game.Players.LocalPlayer local character local humanoid local canDoubleJump = false local hasDoubleJumped = false local oldPower local TIME_BETWEEN_JUMPS = 0.2 local DOUBLE_JUMP_POWER_MULTIPLIER = 2 function onJumpRequest() if not character or not humanoid or not character:IsDescendantOf(workspace) or humanoid:GetState() == Enum.HumanoidStateType.Dead then return end if canDoubleJump and not hasDoubleJumped then hasDoubleJumped = true humanoid.JumpPower = oldPower * DOUBLE_JUMP_POWER_MULTIPLIER humanoid:ChangeState(Enum.HumanoidStateType.Jumping) 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)

Anyone who joins your game can now double jump as they wish.

Conclusion

Double jumping is a useful mechanic to add depth to your game. There are some things that you might want to tweak, such as TIME_BETWEEN_JUMPS and DOUBLE_JUMP_POWER_MULTIPLIER, to change how long after the first jump a player must wait before double jumping or the power of the double jump respectively.

Toplist

Latest post

TAGs