Stamina System has many bugs and i dont know how to fix it

this script is supposed to be a sprint system with stamina. the stamina sort of works but has problems.

  • after reaching 0 stamina and you start sprinting again. for a certain amount of time when you run your stamina will still regenerate and not decrease
  • sometimes the stamina just freezes (no idea why)

no errors pop up in the developer console so i dont know where it goes wrong

local userinputservice = game:GetService('UserInputService')
local tweenservice = game:GetService('TweenService')
local plr = game:GetService("Players").LocalPlayer
local char = workspace:WaitForChild(plr.Name)
local hum = char:WaitForChild('Humanoid')
local camera = workspace.CurrentCamera

local plrgui = plr.PlayerGui

local staminaGUI = plrgui.mainPlayerGui.Frame.TextLabel

local sprintanim = 17713474483
local runningSpeed = 35
local normalSpeed = 12 
local fieldOfView = 80  

local runAnimation = Instance.new('Animation')
runAnimation.AnimationId = 'rbxassetid://'..sprintanim
local rAnimation = hum:LoadAnimation(runAnimation)
local running = false
local stamina = 100
local regen = true
local regencooldown = 0.15
local losecooldown = 0.05


local tweeninfo = TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)

userinputservice.InputBegan:Connect(function(input, isTyping)
	if isTyping then return end
	if input.UserInputType == Enum.UserInputType.Keyboard then
		if userinputservice:IsKeyDown(Enum.KeyCode.W) and userinputservice:IsKeyDown(Enum.KeyCode.LeftShift) and stamina > 0 then
			hum.WalkSpeed = runningSpeed
			tweenservice:Create(camera, tweeninfo, {FieldOfView = fieldOfView}):Play()
			running = true
			regen = false
		end
	end
end)

userinputservice.InputEnded:Connect(function(input, isTyping)
	if isTyping then return end
	if input.UserInputType == Enum.UserInputType.Keyboard then
		if input.KeyCode == Enum.KeyCode.LeftShift or input.KeyCode == Enum.KeyCode.W then
			hum.WalkSpeed = normalSpeed
			tweenservice:Create(camera, tweeninfo, {FieldOfView = 70}):Play()
			running = false
			regen = false
		end
	end
end)

hum.Running:Connect(function(speed)
	if speed >= 10 and running and not rAnimation.IsPlaying and stamina > 0  then
		rAnimation:Play()
		hum.WalkSpeed = runningSpeed
		tweenservice:Create(camera, tweeninfo, {FieldOfView = fieldOfView}):Play()
		regen = false
	elseif speed >= 10 and not running and rAnimation.IsPlaying and stamina > 0 then
		rAnimation:Stop()
		hum.WalkSpeed = normalSpeed
		tweenservice:Create(camera, tweeninfo, {FieldOfView = 70}):Play()
		coroutine.wrap(function()
			task.wait(1)
			if not running then
				regen = true
			end
			
		end)()
	elseif speed < 10 and rAnimation.IsPlaying and stamina > 0 then
		rAnimation:Stop()
		hum.WalkSpeed = normalSpeed
		tweenservice:Create(camera, tweeninfo, {FieldOfView = 70}):Play()
		coroutine.wrap(function()
			task.wait(1)
			if not running then
				regen = true
			end
		end)()
		
	end
end)

hum.Changed:connect(function()
	if hum.Jump and rAnimation.IsPlaying then
		rAnimation:Stop()
	end
end)

while true do
	if regen and stamina < 100 then
			stamina += 1
			task.wait(regencooldown)
	elseif running and stamina > 0 then
	stamina -= 1
	task.wait(losecooldown)
	end
	if stamina > 100 then
		stamina = 100
	elseif stamina <= 0 then
		regen = false
		stamina = 0
		running = false
		rAnimation:Stop()
		hum.WalkSpeed = normalSpeed
		tweenservice:Create(camera, tweeninfo, {FieldOfView = 70}):Play()
		coroutine.wrap(function()
			task.wait(5)
			regen = true
		end)()
	end
	staminaGUI.Text = stamina
	task.wait()
end

I wouldnt tie the stamina system to a userinputservice but i dont think thats gonna matter, i have an question; does the script get readded when your character respawns or is it permanant?

readded, its in startercharacterscripts

Id tie everything to the humanoids attributes, events are instant, its kind of a messy code, you can detect the speed by doing rootPart.Velocity.Magnitude

Im sorry im not too helpful but im trying my best

Try to debug EVERYTHING, thats what i do when something isnt working, like, put a warn/print everywhere where you can

1 Like

yeh i might just rescript the thing or even just follow a tutorial. im not too sure

Hey! I worked on a similar system a while back and I think using RunService.Heartbeat is better than a while loop.
Make a function like UpdateStamia and call it in RunService.Heartbeat, in that function you can do all of your math and if cycles.
And maybe try decreasing the stamina with something like

stamina = math.max(stamina - staminaDecreaseRate, 0)
wait(1)

and regenerate it with

stamina = math.min(stamina + staminaRegenRate, maxStamina)
wait(1)

Here are the veriables I used, you could of course adjust them

local RunSpeed = 25
local maxStamina = 1000
local staminaRegenRate = 1
local staminaDecreaseRate = 1
local sprintCooldown = 10
local stamina = maxStamina

I have a movemwnt system done, its just a module, if you are interested, i could give it to you after i implemented stamina

i think i may redo my system or something, ill try these out in the new system

hmmm sure, ill have a look at it once your finished

rn i have this for the rescript

local contextactionservice = game:GetService('ContextActionService')
local userinputservice = game:GetService('UserInputService')
local tweenservice = game:GetService('TweenService')
local camera = workspace.CurrentCamera

local fieldOfView = 80
local tweeninfo = TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)

local char = script.Parent
local hum = char:WaitForChild('Humanoid')

local function sprint(actionName, inputState, inputType)
	if inputState == Enum.UserInputState.Begin and userinputservice:IsKeyDown(Enum.KeyCode.W) then
		hum.WalkSpeed = hum:GetAttribute("SprintSpeed")
		tweenservice:Create(camera, tweeninfo, {FieldOfView = fieldOfView}):Play()
	elseif inputState == Enum.UserInputState.End then
		hum.WalkSpeed = hum:GetAttribute("BaseWalkSpeed")
		tweenservice:Create(camera, tweeninfo, {FieldOfView = 70}):Play()
	end
end

contextactionservice:BindAction('Sprint', sprint, true, Enum.KeyCode.LeftShift)


how would i make it it only sprints when holding w and stops sprinting when you stop holding w

You can use userinputservice’s
UserInputService.InputBegan and UserInputService.InputEnded

Example:

> UserInputService.InputBegan:Connect(function(input, chat)
> 	if chat then return end 
> 	if input.KeyCode == Enum.KeyCode.LeftShift then 
> 		if canSprint then
> 			Sprint()
> 		else
> 			StopSprint()
> 		end
> 		return
> 	end
> end)

and

> UserInputService.InputEnded:Connect(function(input, chat) 
> 	if chat then return end 
> 
> 	if input.KeyCode == Enum.KeyCode.LeftShift then 
> 		StopSprint()
> 		return
> 	end
1 Like