Inconsistent stamina recharge

I am rather new to scripting and trying to create a stamina system for my game, and I have it mostly figured out except for getting it to regenerate at a steady and consistent rate. If I run out of stamina and let it run its course, it regens fine, but if I spam LeftShift then it starts to overlap on itself and usually regens much faster than intended.
Below is a demonstration of the problem:

I have tried to implement a debounce, but whenever I do, it freezes Studio completely, so that’s not an option. I’ve also tried to rewrite my code multiple times and always end up with the same end result, being that everything but the recharge works properly.

I’ve included the entirety of the script, but the I believe the main problem starts on line 58.

local UIS = game:GetService("UserInputService")

local humanoid = script.Parent.Humanoid

local stamina = Instance.new("IntValue")
stamina.Name = ("Stamina")
stamina.Parent = humanoid.Parent
stamina.Value = 100

local sprinting = Instance.new("BoolValue")
sprinting.Name = ("Sprinting")
sprinting.Parent = humanoid.Parent
sprinting.Value = false

local regen = Instance.new("BoolValue")
regen.Name = ("Regen")
regen.Parent = humanoid.Parent
regen.Value = false
-----------------------------------------------------------------defining stamina value events-----------------------------------------------------------------
stamina.Changed:Connect(function()
	if stamina.Value <= 0 then
		sprinting.Value = false
	end
	if stamina.Value == 100 then
		regen.Value = false
	end
	if stamina.Value >= 100 then
		stamina.Value = 100
		regen.Value = false
	end
end)
-----------------------------------------------------------------defining sprinting value events-----------------------------------------------------------------
sprinting.Changed:Connect(function()
	if sprinting.Value == true and stamina.Value > 0  then
		print("running")
		humanoid.WalkSpeed = 16
		regen.Value = false
	end
	while sprinting.Value == true and stamina.Value > 0  do
		wait(.05)
		stamina.Value -= 1
		print(stamina.Value .. " - using")
	end
end)

sprinting.Changed:Connect(function()
	if sprinting.Value == false then
		print("not running")
		humanoid.WalkSpeed = 8
		if stamina.Value < 100 then
			regen.Value = true
		else
			regen.Value = false
		end
	end
end)
-----------------------------------------------------------------defining regen (probably where the problem is)-----------------------------------------------------------------
regen.Changed:Connect(function()
	while regen.Value == true do
		stamina.Value += 1
		print(stamina.Value .. " - regenerating")
		wait(.2)
	end
	while regen.Value == false do return end
end)
-----------------------------------------------------------------leftshift makes stuff happen-----------------------------------------------------------------
UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.LeftShift and stamina.Value > 0 then
		sprinting.Value = true
	end
end)

UIS.InputEnded:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.LeftShift then
		sprinting.Value = false
		if stamina.Value == 100 then
			regen.Value = false
		end
	end
end)
1 Like

Hey! I revised your script.

local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local humanoid = script.Parent.Humanoid

local stamina = Instance.new("IntValue")
stamina.Name = ("Stamina")
stamina.Parent = humanoid.Parent
stamina.Value = 100

local sprinting = Instance.new("BoolValue")
sprinting.Name = ("Sprinting")
sprinting.Parent = humanoid.Parent
sprinting.Value = false

local regen = Instance.new("BoolValue")
regen.Name = ("Regen")
regen.Parent = humanoid.Parent
regen.Value = false

local regenHeartbeat
-----------------------------------------------------------------defining stamina value events-----------------------------------------------------------------
stamina.Changed:Connect(function()
	if stamina.Value <= 0 then
		sprinting.Value = false
	end
	if stamina.Value == 100 then
		regen.Value = false
	end
	if stamina.Value >= 100 then
		stamina.Value = 100
		regen.Value = false
	end
end)
-----------------------------------------------------------------defining sprinting value events-----------------------------------------------------------------
sprinting.Changed:Connect(function()
	if sprinting.Value == true and stamina.Value > 0  then
		print("running")
		humanoid.WalkSpeed = 16
		regen.Value = false
	end
	while sprinting.Value == true and stamina.Value > 0  do
		wait(.05)
		stamina.Value -= 1
		print(stamina.Value .. " - using")
	end
end)

sprinting.Changed:Connect(function()
	if sprinting.Value == false then
		print("not running")
		humanoid.WalkSpeed = 8
		if stamina.Value < 100 then
			regen.Value = true
		else
			regen.Value = false
		end
	end
end)
-----------------------------------------------------------------defining regen (probably where the problem is)-----------------------------------------------------------------
regen.Changed:Connect(function()
	if regen == true then
		regenHeartbeat = RunService.Heartbeat:Connect(function()
			stamina.Value += 1
			print(stamina.Value .. " - regenerating")
			wait(.2)
		end)
	else
		regenHeartbeat:Disconnect()
	end
end)
-----------------------------------------------------------------leftshift makes stuff happen-----------------------------------------------------------------
UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.LeftShift and stamina.Value > 0 then
		sprinting.Value = true
	end
end)

UIS.InputEnded:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.LeftShift then
		sprinting.Value = false
		if stamina.Value == 100 then
			regen.Value = false
		end
	end
end)

All I did was add a function on “regenHeartBeat” and disconnected when your regen is false.

This should work!

When I use your script, whenever it tries to regen, it comes up with the error of “Workspace.medium_rifle.sprint:69: attempt to index nil with ‘Disconnect’”. I have no clue how functions work so I have no idea what to do to fix this.

You can add a boolean to check if the code is still waiting to count down the stamina recharge. If the player attempts to press shift, or in this case, spam shift, the play will not activate the stamina until the boolean is true or false, depending on what you assign it.

This worked, thank you! It’s odd, because it’s basically the same method as the debounce I had tried previously, yet it works now and doesn’t freeze Studio.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.