Hello everyone!
I currently give up, I’ve been coding this stamina system for about 3 days now I tried and tried and came here for help.
The problem is with refilling my stamina after draining, it works for a bit then it freaks out and bugs like crazy.
My stamina is inspired by Reason 2 Die’s Stamina system preview down (What I want my stamina to look like) below:
My Stamina showcase (tried to compress it so save some quality):
My full script is listed below also:
--// Services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
--// Client
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local Player = Players:GetPlayerFromCharacter(Character)
--// Variables
local SprintTick = 0
--// Status
local Status = Character:WaitForChild("Status")
local Checks = Status:WaitForChild("Checks")
local Stamina = Status:WaitForChild("Stamina")
local IsSprinting =Checks:WaitForChild("IsSprinting").Value
--// Functions
local function RefillStam()
task.wait(3)
while (Stamina.Value < Stamina.MaxValue) and not IsSprinting do
local CalcStam = (Stamina.MaxValue/100) * 1.25
Stamina.Value = Stamina.Value + CalcStam
task.wait(0.25)
print(1)
end
end
RunService.Heartbeat:Connect(function()
if tick() - SprintTick > 0.25 then
SprintTick = tick()
if not IsSprinting and (Stamina.Value < Stamina.MaxValue) then
RefillStam()
return
end
end
end)
What my script basically does on the server is check if the player is not sprinting then it checks if we enough stamina then it supposed to wait 3 seconds before checking if we aren’t sprinting and have enough stamina again, then it calculates the amount of stamina to regenerate and wait .25 seconds and repeat.
I know my code is kinda dumb like why combine a while loop with runservice.heartbeat I just got nothing as I am a beginner since I started 3 months ago please tell me what I’m doing wrong.
There is a Health script within the Characters on the workspace, are you accounting for that?
Also pretty sure Stepped is fast enough for this and Heartbeat is way over doing it.
Hello, first, congrats on learning how to script it’s a long journey but take your time.
Now onto the code fix.
You have a few things that seem to be due to a lack of understanding:
Object Values
When dealing with object values and creating a variable you don’t include .Value in the variable. This is because you need to find the value when the variable is called, not defined aka do local IsSprinting = Checks:WaitForChild("IsSprinting")
not local IsSprinting = Checks:WaitForChild("IsSprinting").Value
Debounces
This is how you make sure your functions aren’t stepping on each other’s toes. So simply have a variable (in this case local refilling) that lets you know this functions is already running
RunService
You don’t seem to know whats the difference is between renderstepped, stepped, and heartbeat. So ill just attach a link that should help with that.
Not vs == false
You use not (variable) a lot in your code and I would be careful as you should only use it when you know what the variable should be or when checking if something exists. If you are only having a function run with something is false just do == false, It also helps with readability!
Anyways here’s your fixed code!
repeat task.wait() until game:GetService("Players"):GetPlayerFromCharacter(script.Parent) ~= nil
--// Services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
--// Client
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local Player = Players:GetPlayerFromCharacter(Character)
--// Variables
local Refilling = false
local Pause = false
local SprintTick = 0
--// Status
local Status = Character:WaitForChild("Status")
local Checks = Status:WaitForChild("Checks")
local Stamina = Status:WaitForChild("Stamina")
local IsSprinting =Checks:WaitForChild("IsSprinting").Value
--// Functions
local function RefillStam()
-- Everytime I stop sprinting I would like to add a delay here before regenerating stamina ( task.wait(3) doesn't seem to work )
if Refilling then return end
Refilling = true
if Pause then
task.wait(3)
Pause = false
end
if (Stamina.Value < Stamina.MaxValue) and not IsSprinting and _G.CanUse(Character, "StamRegen") then
local CalcStam = (Stamina.MaxValue/100) * 1.25
Stamina.Value = Stamina.Value + CalcStam
task.wait(0.25)
end
Refilling = false
end
RunService.Heartbeat:Connect(function()
if Humanoid.Health == 0 or not Character.Parent then
return
end
if tick() - SprintTick > 0.25 then
SprintTick = tick()
if Checks:WaitForChild("IsSprinting").Value then
Stamina.Value -= 5
Pause = true
end
end
RefillStam()
end)
Thanks for the help but I still need help on adding a delay before regenerating and after sprinting.
Also edited your fix abit.
New code:
repeat task.wait() until game:GetService("Players"):GetPlayerFromCharacter(script.Parent) ~= nil
--// Services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
--// Client
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local Player = Players:GetPlayerFromCharacter(Character)
--// Variables
local Refilling = false
local SprintTick = 0
--// Status
local Status = Character:WaitForChild("Status")
local Checks = Status:WaitForChild("Checks")
local Stamina = Status:WaitForChild("Stamina")
local IsSprinting =Checks:WaitForChild("IsSprinting").Value
--// Functions
local function RefillStam()
-- Everytime I stop sprinting I would like to add a delay here before regenerating stamina ( task.wait(3) doesn't seem to work )
if Refilling then return end
Refilling = true
if (Stamina.Value < Stamina.MaxValue) and not IsSprinting and _G.CanUse(Character, "StamRegen") then
local CalcStam = (Stamina.MaxValue/100) * 1.25
Stamina.Value = Stamina.Value + CalcStam
task.wait(0.25)
end
Refilling = false
end
RunService.Heartbeat:Connect(function()
if Humanoid.Health == 0 or not Character.Parent then
return
end
if tick() - SprintTick > 0.25 then
SprintTick = tick()
if Checks:WaitForChild("IsSprinting").Value then
Stamina.Value -= 5
end
end
RefillStam()
end)
Ignore these lines of code.
_G.CanUse(Character, "StamRegen")
if tick() - SprintTick > 0.25 then
SprintTick = tick()
if IsSprinting then
Stamina.Value -= 5
end
end
Once again this has to deal with denounces, look at how I used the variable pause to achieve your goal.
repeat task.wait() until game:GetService("Players"):GetPlayerFromCharacter(script.Parent) ~= nil
--// Services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
--// Client
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local Player = Players:GetPlayerFromCharacter(Character)
--// Variables
local Refilling = false
local Pause = false
local SprintTick = 0
--// Status
local Status = Character:WaitForChild("Status")
local Checks = Status:WaitForChild("Checks")
local Stamina = Status:WaitForChild("Stamina")
local IsSprinting =Checks:WaitForChild("IsSprinting").Value
--// Functions
local function RefillStam()
-- Everytime I stop sprinting I would like to add a delay here before regenerating stamina ( task.wait(3) doesn't seem to work )
if Refilling then return end
Refilling = true
if Pause then
task.wait(3)
Pause = false
end
if (Stamina.Value < Stamina.MaxValue) and not IsSprinting and _G.CanUse(Character, "StamRegen") then
local CalcStam = (Stamina.MaxValue/100) * 1.25
Stamina.Value = Stamina.Value + CalcStam
task.wait(0.25)
end
Refilling = false
end
RunService.Heartbeat:Connect(function()
if Humanoid.Health == 0 or not Character.Parent then
return
end
if tick() - SprintTick > 0.25 then
SprintTick = tick()
if Checks:WaitForChild("IsSprinting").Value then
Stamina.Value -= 5
Pause = true
end
end
RefillStam()
end)
No problem, make sure to post it as a solution if it helped (the large explanation I’ll edit it).
And I highly recommend reading up on the topics I posed, best of luck on your journey!
Will do!, also I would like to say “IsSprinting” wasn’t a ObjectValue it’s a DoubleConstrainedValue I should’ve clarified more. Anyways have a good day.