What about, using a RunService connection that will constantly read the stamina value, when it reaches zero it will reduce the player’s speed?
When client starts to use stamina, the RunService will start to drain and read the stamina value, when it reaches zero it will change the speed back to normal.
In that way if player still pressing the left shift but stamina reached 0, it will stop
I want it to decrease the walkspeed back to default after stamina is drained, but if I’ll try to do that inside InputBegan, it will intersect with the stopRunning() in InputEnded when the user stops holding left shift. They both end up going over the limit and give the player infinite stamina.
Whats the deal with implementing the regaining when having the RunService?
You can even do that the RunService controls everything, from draining, changing speed, and refilling too
By adding if statements to the RunService you will control what is doing.
The debounce of the cooldown could be handled with a task.delay() to set to true or false any variable that the RunService is checking
Wel… actually this stamina thing brings to me lot of thoughts about the right implementation…
Is that stamina system important to your game mechanics?
Right now you are using a client side approach to control if player can use sprint or not. Thats easily exploitable. So, is stamina important for your game? (games where exploiters can run faster than others affects the experience?.. probably many of games)
ServerSide check then? checking and setting the speed of the player?
checking magnitude? being authoritative?
idk, lot of questions that are probably important, or just trust new patches against exploiters works better after roblox and synapse made team… idk
eh, since roblox partnered up with synapse I don’t think they will be poking around as much, and I don’t really care about exploiters in this game. It’s a singleplayer horror, so they don’t ruin anyone’s experience.
local maxStamina = 100
local UIS = game:GetService"UserInputService"
local isSprinting
local stamina = maxStamina
local wait = task.wait
local function sprintLogic(isSprinting)
if isSprinting then
hum.WalkSpeed = sprintWalkSpeed
sprintTween:Play()
defaultTween:Cancel()
else
hum.WalkSpeed = defaultWalkSpeed
sprintTween:Cancel()
defaultTween:Play()
end
end
UIS.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.KeyCode == Enum.KeyCode.LeftShift then
isSprinting = true
sprintLogic(isSprinting)
while isSprinting and stamina > 0 do
stamina -= 1
sprintText.Text = stamina/maxStamina
wait(0.1)
end
isSprinting = false
sprintLogic(isSprinting)
end
end)
UIS.InputEnded:Connect(function(input, gpe)
if gpe then return end
if input.KeyCode == Enum.KeyCode.LeftShift then
isSprinting = false
sprintLogic(isSprinting)
repeat
stamina += 1
sprintText.Text = stamina/maxStamina
wait(0.1)
until isSprinting or stamina == maxStamina
end
end)
I did make a stamina system in the past and tried to use RunService loops, but found that using “traditional” loops worked better because they yield the script while they run which in a stamina system could be used to the scripter’s advantage to make the system much simpler
actually there was a slight hitch: the stamina regened extremely fast if you’ll press shift again while it is already regening. I just made a check if it’s regening, before starting the said regen.
if not isRegening then
task.wait(1.5)
isRegening = true
repeat
stamina += 1
sprintText.Text = stamina.. "/" ..maxStamina
tweenBar(stamina/maxStamina)
wait(0.1)
until isSprinting or stamina == maxStamina
isRegening = false
end