I found a script that adds a Jump Cooldown, and I was trying to modify it so that instead of Jump Cooldown, it introduces Jump Fatigue. Jump Fatigue is a little different because it gradually limits your Jump Height, and after 1 second from the first jump, it resets, as compared to Jump Cooldown where you jump and then have to wait another second to jump again.
I’m having trouble making these changes, If anyone has any ideas or a post already made explaining how to make a jump fatigue script, let me know!
Jump Cooldown Script:
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = script.Parent
local Humanoid = script.Parent:WaitForChild("Humanoid")
local Landed = 0
local JumpState = true
local Jumping = false
local function SetJumpState(state)
-- Avoid calling Humanoid:SetStateEnabled more than once
if JumpState ~= state then
JumpState = state
Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, state)
end
end
local function OnCharacter(character)
Character = character
Humanoid = character:FindFirstChildOfClass("Humanoid")
Humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
if Humanoid.FloorMaterial ~= Enum.Material.Air and Jumping and JumpState then
Landed = tick()
Jumping = false
SetJumpState(false)
end
end)
end
if Player.Character then
OnCharacter(Player.Character)
end
Player.CharacterAdded:Connect(function(character)
Landed = 0
JumpState = true
Jumping = false
OnCharacter(character)
end)
RunService.Heartbeat:Connect(function()
if not JumpState and tick() - Landed > 0.5 then
SetJumpState(true)
end
end)
UserInputService.JumpRequest:Connect(function()
if Humanoid.FloorMaterial ~= Enum.Material.Air then
Jumping = true
end
end)
Just to clarify before I try to create something that answers your question: Is Humanoid.UseJumpPower enabled for the Characters in your game, or do you want to use the JumpHeight property to create a “Jump Fatigue” feature, instead?
Edit: In addition to that, when you mentioned this:
Would you want it to reset 1 second after the Character lands on the ground as a result of jumping? And if a player tries to jump again within that timeframe (before it resets), their jump power / height would continue decreasing and the 1 second timer would restart after they land again? Just want to make sure I understand the specific implementation that you are trying to achieve
-- Jump Fatigue Script (Client - StarterCharacterScripts)
-- Config
local TIME_TO_RESET = 5 -- In seconds
local DECREASE_POWER = 10
local DECREASE_HEIGHT = 1
-- Variables
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = script.Parent
local Humanoid: Humanoid = script.Parent:WaitForChild("Humanoid")
local DefaultPower = Humanoid.JumpPower
local DefaultHeight = Humanoid.JumpHeight
local Landed = 0
local Jumping = false
-- Functions
local function SetJumpAmount(reset: boolean)
if Humanoid.UseJumpPower then
if reset then
Humanoid.JumpPower = DefaultPower
else
Humanoid.JumpPower -= DECREASE_POWER
end
else
if reset then
Humanoid.JumpHeight = DefaultHeight
else
Humanoid.JumpHeight -= DECREASE_HEIGHT
end
end
end
local function OnCharacter(character)
Character = character
Humanoid = character:FindFirstChildOfClass("Humanoid")
Humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
if Humanoid.FloorMaterial ~= Enum.Material.Air and Jumping then
Landed = tick()
Jumping = false
SetJumpAmount(false)
end
end)
end
-- Initialize
if Player.Character then
OnCharacter(Player.Character)
end
Player.CharacterAdded:Connect(function(character)
Landed = 0
Jumping = false
OnCharacter(character)
end)
RunService.Heartbeat:Connect(function()
if tick() - Landed > TIME_TO_RESET then
SetJumpAmount(true)
end
end)
UserInputService.JumpRequest:Connect(function()
if Humanoid.FloorMaterial ~= Enum.Material.Air then
Jumping = true
end
end)
i have jump fatigue implemented in a custom movement system that I wrote a few weeks ago–
the code in the video uses very different code than shown below, but this is how i generally implemented jump fatigue:
---game/StarterPlayer/StarterCharacterScripts/Fatigue.client.lua
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid: Humanoid = Character:WaitForChild("Humanoid")
local JumpPower = 50
local JumpFatigueScalar = 0.5
local JumpFatigueCooldown = 2
local LastNonFatigueJump = 0
local UseFatigueGradient = false
local function Lerp(v0: number, v1: number, a: number): number
return (1 - a) * v0 + a * v1
end
local function IsJumpFatigued(): (boolean, number)
local delta = os.clock() - LastNonFatigueJump
return delta < JumpFatigueCooldown, delta / JumpFatigueCooldown
end
local function StateChanged(_, New: Enum.HumanoidStateType)
if New ~= Enum.HumanoidStateType.Jumping then return end
local IsFatigued, Gradient = IsJumpFatigued()
if IsFatigued then
if UseFatigueGradient then
Humanoid.JumpPower = Lerp(JumpPower * JumpFatigueScalar, JumpPower, Gradient)
else
Humanoid.JumpPower = JumpPower * JumpFatigueScalar
end
else
Humanoid.JumpPower = JumpPower
LastNonFatigueJump = os.clock()
end
end
Humanoid.StateChanged:Connect(StateChanged)
there’s also a setting for the jump fatigue to gradually increase as the cooldown approaches 0, which i personally don’t really like but it’s possible anyway so here’s a pretty picture i drew that shows how either settings will affect jumppower
This is exactly what I need! Very organized script btw and stupid proof too, I like it! (if Humanoid.UseJumpPower then) Anyways I was trying to make a jump fatigue system similar to the game Fortnite and just found out that they have it a little different to the one I asked for:
Jump fatigue begins after jumping twice and starts at the beginning of your second jump.
Jump fatigue resets if you wait about 1 second after the start of your last jump not the beginning jump.
Do you mind adjusting accordingly? I can pay 100 robux for your time.
Alright. It’s not perfect, but I have a system that works pretty well.
Details:
It’s a lot more “full” than the last script (lol), but it works. There are several new configuration options that allow you to tweak everything to your liking.
Configuration:
JUMPS_TO_START -- Amount of jumps to trigger fatigue
TIME_TO_START -- Amount of time after the last jump number to start degrading
TIME_TO_RESET -- Amount of time after the last jump to activate recovery
GRADUAL_RESET -- Gradually reset the jump power/height (Instantly resets if false)
INCREAST_PER_SEC -- Amount of times per second the jump power/height increases
INCREASE_POWER -- Amount of power that is increased during gradual recovery
INCREASE_HEIGHT -- Amount of height that is increased during gradual recovery
DECREASE_POWER -- Amount of power that is decreased after each jump
DECREASE_HEIGHT -- Amount of power that is decreased after each jump
MIN_POWER -- The minimum jump power that can be set
MIN_HEIGHT -- The minimum jump height that can be set
USE_MIN_JUMP -- If true, uses MIN_POWER and MIN_HEIGHT
I have pre-configured everything to match what you have described in the replies above, however, feel free to adjust anything you want to test things out.
Script:
-- Jump Fatigue Script (Client - StarterCharacterScripts)
-- Constants
local JUMPS_TO_START = 2 -- Amount of jumps to trigger fatigue (Starts on the last jump number)
local TIME_TO_START = 1 -- Amount of time after the last jump number to start degrading
local TIME_TO_RESET = 1 -- Amount of time after the last jump to activate recovery
local GRADUAL_RESET = false -- Gradually reset the jump power/height (Instantly resets if false)
local INCREASE_PER_SEC = 2 -- Amount of times per second the jump power/height will increase (Ignore if above is false)
local INCREASE_POWER = 10 -- Amount of power that is increased during gradual recovery (JumpPower)
local INCREASE_HEIGHT = 1 -- Amount of height that is increased during gradual recovery (JumpHeight)
local DECREASE_POWER = 10 -- Amount of power that is decreased after each jump (JumpPower)
local DECREASE_HEIGHT = 1 -- Amount of height that is decreased after each jump (JumpHeight)
local MIN_POWER = 20 -- The minimum jump power that can be set
local MIN_HEIGHT = 2 -- The minimum jump height that can be set
local USE_MIN_JUMP = true -- If true, will use the MIN_POWER and MIN_HEIGHT values
-- Variables
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = script.Parent
local Humanoid: Humanoid = script.Parent:WaitForChild("Humanoid")
local DefaultPower = Humanoid.JumpPower
local DefaultHeight = Humanoid.JumpHeight
local Landed = 0
local TimesJumped = 0
local Jumping = false
local Degrading = false
local Increasing = false
-- Functions
local function ChangeJumpPower(amount: number)
if USE_MIN_JUMP and (amount) < MIN_POWER then return end
if amount > DefaultPower then Humanoid.JumpPower = DefaultPower return end
Humanoid.JumpPower = amount
end
local function ChangeJumpHeight(amount: number)
if USE_MIN_JUMP and (amount) < MIN_HEIGHT then return end
if amount > DefaultHeight then Humanoid.JumpHeight = DefaultHeight return end
Humanoid.JumpHeight = amount
end
local function SetJumpFatigue(reset: boolean)
if Humanoid.UseJumpPower then
if reset and not Increasing then
Increasing = true
Degrading = false
if GRADUAL_RESET then
repeat
ChangeJumpPower(Humanoid.JumpPower + INCREASE_POWER)
task.wait(1/INCREASE_PER_SEC)
until
Humanoid.JumpPower >= DefaultPower
else
ChangeJumpPower(DefaultPower)
end
Increasing = false
elseif not Increasing then
ChangeJumpPower(Humanoid.JumpPower - DECREASE_POWER)
end
else
if reset and not Increasing then
Increasing = true
Degrading = false
if GRADUAL_RESET then
repeat
ChangeJumpHeight(Humanoid.JumpHeight + INCREASE_HEIGHT)
task.wait(1/INCREASE_PER_SEC)
until
Humanoid.JumpHeight >= DefaultHeight
else
ChangeJumpHeight(DefaultHeight)
end
Increasing = false
elseif not Increasing then
ChangeJumpHeight(Humanoid.JumpHeight - DECREASE_HEIGHT)
end
end
end
local function OnCharacter(character)
Character = character
Humanoid = character:FindFirstChildOfClass("Humanoid")
Humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
if Humanoid.FloorMaterial ~= Enum.Material.Air and Jumping then
Landed = tick()
Jumping = false
TimesJumped += 1
if not Degrading and TimesJumped >= JUMPS_TO_START then
repeat task.wait() until tick() - Landed >= TIME_TO_START
SetJumpFatigue(false)
else
SetJumpFatigue(false)
end
Degrading = true
end
end)
end
-- Initialize
if Player.Character then
OnCharacter(Player.Character)
end
Player.CharacterAdded:Connect(function(character)
Landed = 0
Jumping = false
OnCharacter(character)
end)
RunService.Heartbeat:Connect(function()
if tick() - Landed > TIME_TO_RESET then
TimesJumped = 0
Degrading = false
SetJumpFatigue(true)
end
end)
UserInputService.JumpRequest:Connect(function()
if Humanoid.FloorMaterial ~= Enum.Material.Air then
Jumping = true
end
end)
Let me know if you have any further questions or requests!
Few things I noticed right off the bat, Jumps to Start and Time to Start doesn’t seem to be working. When I spam jump it always starts the jump fatigue right away and takes the time from the first jump to reset so maybe just Jumps to Start doesn’t work. Once again I really appreciate your help on this
it works for me on an empty baseplate, maybe u forgot to flip the boolean value of UseFatigueGradient?
also this is a help forum and offering/receiving robux outside of explicit commissions isnt what a help forum is about :^)!
---game/StarterPlayer/StarterCharacterScripts/Fatigue.client.lua
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid: Humanoid = Character:WaitForChild("Humanoid")
local JumpPower = 50
local JumpFatigueScalar = 0.5
local JumpFatigueCooldown = 2
local LastNonFatigueJump = 0
local UseFatigueGradient = true
local function Lerp(v0: number, v1: number, a: number): number
return (1 - a) * v0 + a * v1
end
local function IsJumpFatigued(): (boolean, number)
local delta = os.clock() - LastNonFatigueJump
return delta < JumpFatigueCooldown, 1 - (delta / JumpFatigueCooldown)
end
local function StateChanged(_, New: Enum.HumanoidStateType)
if New ~= Enum.HumanoidStateType.Jumping then return end
local IsFatigued, Gradient = IsJumpFatigued()
if IsFatigued then
if UseFatigueGradient then
Humanoid.JumpPower = Lerp(JumpPower * JumpFatigueScalar, JumpPower, Gradient)
else
Humanoid.JumpPower = JumpPower * JumpFatigueScalar
end
else
Humanoid.JumpPower = JumpPower
LastNonFatigueJump = os.clock()
end
print(Humanoid.JumpPower)
end
Humanoid.StateChanged:Connect(StateChanged)
i didn’t know u wanted it to take 2 jumps to start :p
i rewrote some of the variables to be part of a settings table so u can import custom settings in the future, and also made it so u can define how many jumps it takes for the actual fatigue to be applied, as well as a reset timer so that spaced-out jump inputs can have the internal fatigue counter reset
---game/StarterPlayer/StarterCharacterScripts/Fatigue.client.lua
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid: Humanoid = Character:WaitForChild("Humanoid")
local Settings = {
JumpPower = 50;
JumpFatigueScalar = 0.5;
JumpFatigueCooldown = 2;
--# of jumps executed until fatigue is applied
JumpLenience = 2;
--# of seconds until JumpLenience is reset
JumpLenienceReset = 1;
--jump fatigue follows a linear gradient (true) or a constant gradient (false)
UseFatigueGradient = true;
}
local FatigueStart = 0
local LastNonFatigueJump = 0
local CurrentLenience = Settings.JumpLenience
local function Lerp(v0: number, v1: number, a: number): number
return (1 - a) * v0 + a * v1
end
local function OnNonFatigueJump()
local Now = os.clock()
if Now - LastNonFatigueJump > Settings.JumpLenienceReset then
CurrentLenience = Settings.JumpLenience
end
LastNonFatigueJump = Now
CurrentLenience -= 1
if CurrentLenience == 0 then
FatigueStart = Now
end
end
local function IsJumpFatigued(): (boolean, number)
local delta = os.clock() - FatigueStart
return delta < Settings.JumpFatigueCooldown, 1 - (delta / Settings.JumpFatigueCooldown)
end
local function StateChanged(_, New: Enum.HumanoidStateType)
if New ~= Enum.HumanoidStateType.Jumping then return end
local IsFatigued, Gradient = IsJumpFatigued()
if IsFatigued then
if Settings.UseFatigueGradient then
Humanoid.JumpPower = Lerp(Settings.JumpPower * Settings.JumpFatigueScalar, Settings.JumpPower, Gradient)
else
Humanoid.JumpPower = Settings.JumpPower * Settings.JumpFatigueScalar
end
CurrentLenience = Settings.JumpLenience
else
Humanoid.JumpPower = Settings.JumpPower
OnNonFatigueJump()
end
print(Humanoid.JumpPower)
end
Humanoid.StateChanged:Connect(StateChanged)
Wow this is exactly what I needed! Sorry for the late reply btw was away from my computer for a while. Is there a setting to change if the cooldown starts at the last jump fatigue to reset jump fatigue? (Like a player has to stop jumping for 1 second to reset jump fatigue)
---game/StarterPlayer/StarterCharacterScripts/Fatigue.client.lua
local TS = game:GetService("TweenService")
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid: Humanoid? = Character:FindFirstChildOfClass("Humanoid") or Character:WaitForChild("Humanoid")
local Settings = {
JumpPower = 50;
JumpFatigueScalar = 0.5;
JumpFatigueTime = 1;
--# of jumps executed until fatigue is applied
JumpLenience = 2;
--# of seconds until JumpLenience is reset
JumpLenienceReset = 1;
--apply custom curve to fatigue gradient; set easingstyle enum to "Linear" for a normal gradient
FatigueCurve = {Enum.EasingStyle.Quad, Enum.EasingDirection.In}
}
local FatigueStart = 0
local LastNonFatigueJump = 0
local CurrentLenience = Settings.JumpLenience
local function Lerp(v0: number, v1: number, a: number): number
return (1 - a) * v0 + a * v1
end
local function OnNonFatigueJump(): ()
local Now = os.clock()
if Now - LastNonFatigueJump > Settings.JumpLenienceReset then
CurrentLenience = Settings.JumpLenience
end
LastNonFatigueJump = Now
CurrentLenience -= 1
if CurrentLenience == 0 then
FatigueStart = Now
end
end
local function OnFatigueJump(): ()
local Now = os.clock()
FatigueStart = Now
end
local function IsJumpFatigued(): (boolean, number)
local delta = os.clock() - FatigueStart
return delta < Settings.JumpFatigueTime, 1 - (delta / Settings.JumpFatigueTime)
end
local function StateChanged(_, New: Enum.HumanoidStateType)
if New ~= Enum.HumanoidStateType.Jumping then return end
local IsFatigued, Gradient = IsJumpFatigued()
if IsFatigued then
Humanoid.JumpPower = Lerp(Settings.JumpPower * Settings.JumpFatigueScalar, Settings.JumpPower, TS:GetValue(Gradient, unpack(Settings.FatigueCurve)))
CurrentLenience = Settings.JumpLenience
OnFatigueJump()
else
Humanoid.JumpPower = Settings.JumpPower
OnNonFatigueJump()
end
end
Humanoid.StateChanged:Connect(StateChanged)