How do I fix the framerate and stamina bar issue in this stamina running script?

Alright so here I have a running stamina script, or two actually with the local script, that takes away the player’s stamina as he runs, however I’ve run into two issues.

  1. The Stamina Bar elongates WAY beyond the the borders I have for it and the stamina runs out before the bar reaches 0.

robloxapp-20201210-1029493.wmv (1.3 MB)

2.Whenever I toggle left shift which is the keyCode for the function, the player runs for 2 seconds then stops as opposed to continually running for as long as I have the left shift held down.
Here’s the local script:

local UIS = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.LeftShift then
		ReplicatedStorage.RemoteEvents.Sprint:FireServer("StartedState")
	end
end)

UIS.InputEnded:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.LeftShift then
		ReplicatedStorage.RemoteEvents.Sprint:FireServer("EndedState")
	end
end)

ReplicatedStorage.RemoteEvents.StaminaUpdate.OnClientEvent:Connect(function(Stamina,MaxStamina)
	Players.LocalPlayer.PlayerGui.Stamina.StaminaBar.Size = UDim2.new((Stamina/MaxStamina) * 0,410,0,31)
	
end)

And the Server Script:

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

local MaxStamina = 300
local StaminaRegeneration = 4

local SprintModifier = 2
local SprintStaminaCost = 7

local SprintingPlayers = {}
game.StarterPlayer.EnableMouseLockOption = false


Players.PlayerAdded:Connect(function(Player)
	local Stamina = Instance.new("IntValue",Player)
	Stamina.Value = MaxStamina
	Stamina.Name = "Stamina"
	
	Stamina.Changed:Connect(function(Property)
		ReplicatedStorage.RemoteEvents.StaminaUpdate:FireClient(Player,Stamina.Value,MaxStamina)
	end)
end)

ReplicatedStorage.RemoteEvents.Sprint.OnServerEvent:Connect(function(Player,State)
	local Humanoid = Player.Character.Humanoid
	if State == "StartedState" and Humanoid:GetState() == Enum.HumanoidStateType.RunningNoPhysics and Humanoid.MoveDirection.Magnitude > 0 then
		SprintingPlayers[Player.Name] = Humanoid.WalkSpeed
		Humanoid.WalkSpeed = Humanoid.WalkSpeed * SprintModifier
	elseif
		State == "EndedState" and SprintingPlayers[Player.Name] then
		Humanoid.WalkSpeed = SprintingPlayers[Player.Name]
		SprintingPlayers[Player.Name] = nil
	end
end)

RunService.Heartbeat:Connect(function()
	for i,Player in pairs(Players:GetChildren()) do
		local Stamina = Player.Stamina
		local Name = Player.Name
		
		if not SprintingPlayers[Name] then
			if Stamina.Value > MaxStamina then
				Stamina.Value = MaxStamina
			elseif
				Stamina.Value < MaxStamina then
				Stamina.Value = Stamina.Value + StaminaRegeneration
			
			end
		else
			if Stamina.Value >= SprintStaminaCost then
				Stamina.Value = Stamina.Value - SprintStaminaCost
				
			else
				Player.Character.Humanoid.WalkSpeed = SprintingPlayers[Name]
				SprintingPlayers[Name] = nil
			end
		end
	end
end)

Some guy said this was due to the stamina value being updated at 60 fps and the character sprinting at -7 stamina per frame, hence it takes less than 60 frames to get to 0 which I don’t completely understand. How do I make it so that the character would sprint for a decent amount of time and run out along with the stamina bar rather than the character running in sporadic spurts and the stamina bar elongating beyond it’s borders with the stamina running out before the bar reaches 0.

2 Likes

Maybe comment out the bits doing the stamina and concentrate on why the running stops when shift is unset.