Sprinting System - Not Working Properly

I’m trying to make it so that when isRunning == false or Energy.Value <= 10 then it’ll set the Humanoid’s WalkSpeed back to it’s original but instead it permanently slowing down the character. I know why but I can’t fix it at all since I’ve tried it. When I added the Humanoid.WalkSpeed / 1.5 in the if statement in the repeat that’s inside of the Input Began, it’ll slow down the character but then slow it down again when the player lets go of shift but if I just break the repeat without slowing down the character, it’ll just be an infinite sprinting system.

local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local Player = game.Players.LocalPlayer
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")

local PlayerGui = Player:WaitForChild("PlayerGui")
local StaminaGui = PlayerGui:WaitForChild("StaminaGui")

local StaminaOuterFrame = StaminaGui:WaitForChild("StaminaOuterFrame")
local StaminaInnerFrame = StaminaOuterFrame:WaitForChild("StaminaInnerFrame")

local StaminaText = StaminaInnerFrame:WaitForChild("StaminaText")
local Energy = script:WaitForChild("Energy")

local Rate = 0.05
local isRunning = false

local function UpdateBar()
	while true do
		StaminaText.Text = Energy.Value
		TweenService:Create(StaminaInnerFrame, TweenInfo.new(0.5, Enum.EasingStyle.Linear), {Size = UDim2.new(Energy.Value / 100, 0, 1, 0)}):Play()
		task.wait(0.25)
	end
end

UserInputService.InputBegan:Connect(function(input, processed)
	if processed then return end
	if not processed then
		if input.KeyCode == Enum.KeyCode.LeftShift then
			if Energy.Value >= 10 then
				isRunning = true
				Humanoid.WalkSpeed = Humanoid.WalkSpeed * 1.5
				repeat
					if isRunning == false or Energy.Value <= 10 then
						Humanoid.WalkSpeed = Humanoid.WalkSpeed / 1.5
						break
					end
					Energy.Value -= 1
					task.wait(Rate)
					print("Decreased")
				until Energy.Value <= 10
			else
				return
			end
		else
			return
		end
	end
end)

UserInputService.InputEnded:Connect(function(input, processed)
	if processed then return end
	if not processed then
		if input.KeyCode == Enum.KeyCode.LeftShift then
			isRunning = false
			Humanoid.WalkSpeed = Humanoid.WalkSpeed / 1.5
			repeat
				if isRunning == true or Energy.Value >= 100 then break end
				Energy.Value += 1
				task.wait(Rate)
				print("Increased")
			until Energy.Value >= 100
		else
			return
		end
	end
end)
task.spawn(UpdateBar)

Please help me. I don’t know how to fix it at all :frowning:

1 Like

local TweenService = game:GetService(“TweenService”)
local UserInputService = game:GetService(“UserInputService”)
local Player = game.Players.LocalPlayer
local Character = script.Parent
local Humanoid = Character:WaitForChild(“Humanoid”)

local PlayerGui = Player:WaitForChild(“PlayerGui”)
local StaminaGui = PlayerGui:WaitForChild(“StaminaGui”)

local StaminaOuterFrame = StaminaGui:WaitForChild(“StaminaOuterFrame”)
local StaminaInnerFrame = StaminaOuterFrame:WaitForChild(“StaminaInnerFrame”)

local StaminaText = StaminaInnerFrame:WaitForChild(“StaminaText”)
local Energy = script:WaitForChild(“Energy”)

local Rate = 0.05
local isRunning = false
local originalWalkSpeed = Humanoid.WalkSpeed – Store original walk speed

local function UpdateBar()
while true do
StaminaText.Text = Energy.Value
TweenService:Create(StaminaInnerFrame, TweenInfo.new(0.5, Enum.EasingStyle.Linear), {Size = UDim2.new(Energy.Value / 100, 0, 1, 0)}):Play()
task.wait(0.25)
end
end

UserInputService.InputBegan:Connect(function(input, processed)
if processed then return end
if input.KeyCode == Enum.KeyCode.LeftShift and Energy.Value >= 10 then
isRunning = true
Humanoid.WalkSpeed = originalWalkSpeed * 1.5
repeat
if not isRunning or Energy.Value <= 10 then
Humanoid.WalkSpeed = originalWalkSpeed – Reset to original speed
break
end
Energy.Value -= 1
task.wait(Rate)
print(“Decreased”)
until Energy.Value <= 10
end
end)

UserInputService.InputEnded:Connect(function(input, processed)
if processed then return end
if input.KeyCode == Enum.KeyCode.LeftShift then
isRunning = false
Humanoid.WalkSpeed = originalWalkSpeed – Reset to original speed
repeat
if isRunning or Energy.Value >= 100 then break end
Energy.Value += 1
task.wait(Rate)
print(“Increased”)
until Energy.Value >= 100
end
end)

task.spawn(UpdateBar)

1 Like

My game has a speed buff and it lasts for 60 seconds so I don’t think storing the original walk speed would do it.

You can create an attribute in the player then to store their walkspeed instead of locally in a script, this way you can access the original walkspeed at anytime

Character:SetAttribute("OriginalWalkspeed", 16)

Humanoid.Walkspeed = Character:GetAttribute("OriginalWalkspeed")

If you have a speed boost, you can increase the originalwalkspeed attribute then set it back to the original eg.

Character:SetAttribute("OriginalWalkspeed", 24)
task.wait(60)
Character:SetAttribute("OriginalWalkspeed", 16)

Hm… alright, I guess I will try that :thinking:

Wait? How will this work though? Will it keep updating the attribute walkspeed everytime?

tbh tho I don’t think attributes are really needed. All I need is to find some way to lower player’s speed when Energy.Value <= 10 and not do it again when they let go of shift.

Nvm i see the issue:

You should remove Humanoid.WalkSpeed = Humanoid.WalkSpeed / 1.5 from InputBegan when it checks if running is false & slows the player down

if isRunning == false or Energy.Value <= 10 then
	Humanoid.WalkSpeed = Humanoid.WalkSpeed / 1.5
	break
end

This is because from inputended, you’re already slowing the player down WHEN they let go of the shift key, so when you let go of the shift key the InputBegan and InputEnded will both slow the player down

UserInputService.InputEnded:Connect(function(input, processed)
	if processed then return end
	if not processed then
		if input.KeyCode == Enum.KeyCode.LeftShift then
			isRunning = false
			Humanoid.WalkSpeed = Humanoid.WalkSpeed / 1.5
			repeat
				if isRunning == true or Energy.Value >= 100 then break end
				Energy.Value += 1
				task.wait(Rate)
				print("Increased")
			until Energy.Value >= 100
		else
			return
		end
	end
end)

That was exactly my point… If I remove it then if the player’s Energy <=10 then how will the player’s speed slow down? It will only AND ONLY slow down when they let go of shift.

local Rate = 0.05
local DecrementRate = 1
local IncrementRate = 1
local isRunning = false
local OriginalWalkSpeed = Humanoid.WalkSpeed

local function UpdateBar()
	while true do
		StaminaText.Text = tostring(Energy.Value) .. "%"
		TweenService:Create(StaminaInnerFrame, TweenInfo.new(0.25, Enum.EasingStyle.Linear), {Size = UDim2.new(Energy.Value / 100, 0, 1, 0)}):Play()
		task.wait(0.25)
	end
end

UserInputService.InputBegan:Connect(function(input, processed)
	if processed or input.KeyCode ~= Enum.KeyCode.LeftShift then return end
	if Energy.Value > 0 then
		isRunning = true
		Humanoid.WalkSpeed = OriginalWalkSpeed * 1.5
		repeat
			if not isRunning or Energy.Value <= 0 then
				Humanoid.WalkSpeed = OriginalWalkSpeed
				break
			end
			Energy.Value = math.max(Energy.Value - DecrementRate, 0)
			task.wait(Rate)
		until Energy.Value <= 0
		Humanoid.WalkSpeed = OriginalWalkSpeed
	end
end)

UserInputService.InputEnded:Connect(function(input, processed)
	if processed or input.KeyCode ~= Enum.KeyCode.LeftShift then return end
	isRunning = false
	Humanoid.WalkSpeed = OriginalWalkSpeed
	repeat
		if isRunning or Energy.Value >= 100 then break end
		Energy.Value = math.min(Energy.Value + IncrementRate, 100)
		task.wait(Rate)
	until Energy.Value >= 100
end)

task.spawn(UpdateBar)

I went to 0 because well, :sunglasses:. You can put back your <=10 if you like…

My actual test
local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local Player = game.Players.LocalPlayer
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local PlayerGui = Player:WaitForChild("PlayerGui")

local StaminaGui = PlayerGui:FindFirstChild("StaminaGui") or Instance.new("ScreenGui", PlayerGui)
StaminaGui.Name = "StaminaGui"

local StaminaOuterFrame = StaminaGui:FindFirstChild("StaminaOuterFrame") or Instance.new("Frame", StaminaGui)
StaminaOuterFrame.Name = "StaminaOuterFrame"
StaminaOuterFrame.Size = UDim2.new(0.3, 0, 0.05, 0)
StaminaOuterFrame.Position = UDim2.new(0.35, 0, 0.9, 0)
StaminaOuterFrame.BorderSizePixel = 0
StaminaOuterFrame.BackgroundColor3 = Color3.fromRGB(0, 0, 0)

local StaminaInnerFrame = StaminaOuterFrame:FindFirstChild("StaminaInnerFrame") or Instance.new("Frame", StaminaOuterFrame)
StaminaInnerFrame.Name = "StaminaInnerFrame"
StaminaInnerFrame.Size = UDim2.new(1, 0, 1, 0)
StaminaInnerFrame.BorderSizePixel = 0
StaminaInnerFrame.BackgroundColor3 = Color3.fromRGB(0, 255, 0)

local StaminaText = StaminaInnerFrame:FindFirstChild("StaminaText") or Instance.new("TextLabel", StaminaInnerFrame)
StaminaText.Name = "StaminaText"
StaminaText.Size = UDim2.new(1, 0, 1, 0)
StaminaText.BackgroundTransparency = 1
StaminaText.TextColor3 = Color3.fromRGB(255, 255, 255)
StaminaText.TextScaled = true
StaminaText.Font = Enum.Font.SourceSansBold

local Energy = script:FindFirstChild("Energy") or Instance.new("IntValue", script)
Energy.Name = "Energy"
Energy.Value = 100

local Rate = 0.05
local DecrementRate = 1
local IncrementRate = 1
local isRunning = false
local OriginalWalkSpeed = Humanoid.WalkSpeed

local function UpdateBar()
	while true do
		StaminaText.Text = tostring(Energy.Value) .. "%"
		TweenService:Create(StaminaInnerFrame, TweenInfo.new(0.25, Enum.EasingStyle.Linear), {Size = UDim2.new(Energy.Value / 100, 0, 1, 0)}):Play()
		task.wait(0.25)
	end
end

UserInputService.InputBegan:Connect(function(input, processed)
	if processed or input.KeyCode ~= Enum.KeyCode.LeftShift then return end
	if Energy.Value > 0 then
		isRunning = true
		Humanoid.WalkSpeed = OriginalWalkSpeed * 1.5
		repeat
			if not isRunning or Energy.Value <= 0 then
				Humanoid.WalkSpeed = OriginalWalkSpeed
				break
			end
			Energy.Value = math.max(Energy.Value - DecrementRate, 0)
			task.wait(Rate)
		until Energy.Value <= 0
		Humanoid.WalkSpeed = OriginalWalkSpeed
	end
end)

UserInputService.InputEnded:Connect(function(input, processed)
	if processed or input.KeyCode ~= Enum.KeyCode.LeftShift then return end
	isRunning = false
	Humanoid.WalkSpeed = OriginalWalkSpeed
	repeat
		if isRunning or Energy.Value >= 100 then break end
		Energy.Value = math.min(Energy.Value + IncrementRate, 100)
		task.wait(Rate)
	until Energy.Value >= 100
end)

task.spawn(UpdateBar)
1 Like

My game in it has a speed buff though. You can’t just store the original walk speed.

Well … isn’t the original walk speed going to be 16 no matter what?

No…? There’s a speed when u spawn in and then there’s gonna be the new speed when u get the speed buff and then there’s the sprinting system increment speed.

Oh I see
I did some testing with your script on a new place, it was an issue on how the Energy.Value was being checked & the energy.
I made a value for IsRunning (instead of a variable) inside the script and checked whenever it becomes false or not to change the walkspeed based on that & used GetPropertyChangedSignal to see if the energy becomes 10 or less to change IsRunning to false,

place i tested if u need it:
SprintingFix.rbxl (55.9 KB)

video of the fix:
robloxapp-20241117-0035475.wmv (1.5 MB)

local Rate = 0.05
local isRunning = script.IsRunning

local function UpdateBar()
	while true do
		StaminaText.Text = Energy.Value
		TweenService:Create(StaminaInnerFrame, TweenInfo.new(0.5, Enum.EasingStyle.Linear), {Size = UDim2.new(Energy.Value / 100, 0, 1, 0)}):Play()
		task.wait(0.25)
	end
end

UserInputService.InputBegan:Connect(function(input, processed)
	if input.KeyCode == Enum.KeyCode.LeftShift then
		if Energy.Value > 10 then
			isRunning.Value = true
			repeat
				if isRunning.Value == false or Energy.Value <= 10 then
					isRunning.Value = false
					break
				end
				Energy.Value -= 1
				task.wait(Rate)
				print("Decreased")
			until Energy.Value <= 10
		end
	end
end)
	
UserInputService.InputEnded:Connect(function(input, processed)
	if input.KeyCode == Enum.KeyCode.LeftShift then
		isRunning.Value = false
		repeat
			if isRunning.Value == true or Energy.Value >= 100 then break end
			Energy.Value += 1
			task.wait(Rate)
			print("Increased")
		until Energy.Value >= 100
	end
end)
	
	
	
isRunning:GetPropertyChangedSignal("Value"):Connect(function()
	if isRunning.Value == true then
		print('increased walkspeed')
		Humanoid.WalkSpeed = Humanoid.WalkSpeed * 1.5
	elseif isRunning.Value == false then
		print('decreased walkspeed')
		Humanoid.WalkSpeed = Humanoid.WalkSpeed / 1.5
	end
end)
	
Energy:GetPropertyChangedSignal("Value"):Connect(function()
	if Energy.Value <= 10 then
		isRunning.Value = false
	end
end)

Wait where is the script located in? My script is in starter character scripts

The way I do it is storing the current walkspeed as the humanoid walkspeed, and then keep a “movementspeed” stat in the player’s stat folder. That way it’s easy to manage changes to humanoid stats.

if isSprinting.Value == true then

	humanoid.WalkSpeed = math.ceil(movementSpeed.Value * 1.4)

hmmmmm alr… Never heard of doing that but ok

In startercharacterscripts too
image

Oh alright. I’ll try your script. I hope it works :smiley: