How to end an Input on a condition?

So im having a problem with this movement script.

Specifically on the UIS.Input.Began:Connect i want it to end when the Stamina Attribute hits 0 but just couldnt figure out how to. i tried breaking and setting the OnHold to false when the stamina hits 0 but as long as the player hold shift it’ll still run.

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

local plr = Players.LocalPlayer
local char = plr.Character
local humanoid = char:WaitForChild("Humanoid")

local BaseSpeed = 8
local MaxSpeed = 20
local SpeedRate = .5

local DecayRate = -.1 --always negative

local OnHold = false
local W_Hold = false
local HoldTime = 0

local MaxStamina = 100
plr:SetAttribute("Stamina", 100)


local function UpdateStamina()
	while true do
		if not OnHold and plr:GetAttribute("Stamina") < MaxStamina then
			local currentStamina = plr:GetAttribute("Stamina")

			local AddStamina = math.min(currentStamina + 5, MaxStamina)
			plr:SetAttribute("Stamina", AddStamina)
		end
		wait(3)
	end
end

task.spawn(UpdateStamina)


UIS.InputBegan:Connect(function(input, gameProccessed)
	
	if gameProccessed then return end
	
	if input.KeyCode == Enum.KeyCode.W then
		W_Hold = true
	end
	
	
	if input.KeyCode == Enum.KeyCode.LeftShift and W_Hold then
		
		OnHold = true
		HoldTime  = 0
		
		while OnHold and W_Hold do

			print(stamina)
			
			if stamina <= 0 then
				OnHold = false
				break
			end
			
			
			if plr:GetAttribute("Stamina") <= 1 then
				break
			end
			
			local stamina = plr:GetAttribute("Stamina")
			
			local MinusStamina = stamina - 1
			plr:SetAttribute("Stamina",math.max(MinusStamina, 0) )
			
			HoldTime += .1
			
			local Speed = BaseSpeed * math.exp(SpeedRate * HoldTime)
			Speed = math.clamp(Speed, BaseSpeed, MaxSpeed)
			humanoid.WalkSpeed = Speed
			
			local Delay = 1 / (Speed - BaseSpeed + 1)
			
			wait(Delay)

		end
	end
end)

UIS.InputEnded:Connect(function(input)
	
	if input.KeyCode == Enum.KeyCode.W then
		W_Hold = false
	end
	
	if input.KeyCode == Enum.KeyCode.LeftShift then
		OnHold = false
		while humanoid.WalkSpeed > BaseSpeed do
			
			local CurSpd = humanoid.WalkSpeed 
			local NewSpd = CurSpd * math.exp(DecayRate)
			humanoid.WalkSpeed = math.max(BaseSpeed, NewSpd)
			
			wait(.1)
			
		end
	end
end)

Try moving the decrease stamina line after the wait delay, it could be something fishy with the order the lines are run. But the break statement should work.

1 Like

first things first, you shouldn’t use wait(), use task.wait() instead.
Also declare the “stamina” variable before the cycle:

OnHold = true
HoldTime  = 0
local stamina = plr:GetAttribute("Stamina")

I’m gonna send you the updated version of your code

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

local plr = Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local humanoid = char:WaitForChild("Humanoid")

local BaseSpeed = 8
local MaxSpeed = 20
local SpeedRate = 3 --changed a little bit

local DecayRate = -.1 --always negative

local shiftHold = false
local wHold = false

local MaxStamina = 100
plr:SetAttribute("Stamina", 100)


local function updateStamina()
	while true do
		if not shiftHold and plr:GetAttribute("Stamina") < MaxStamina then
			local currentStamina = plr:GetAttribute("Stamina")

			local AddStamina = math.min(currentStamina + 5, MaxStamina)
			plr:SetAttribute("Stamina", AddStamina)
		end
		wait(3)
	end
end

task.spawn(updateStamina)

local function onShiftRelease()
	shiftHold = false
	while humanoid.WalkSpeed > BaseSpeed do

		local CurSpd = humanoid.WalkSpeed 
		local NewSpd = CurSpd * math.exp(DecayRate)
		humanoid.WalkSpeed = math.max(BaseSpeed, NewSpd)

		wait(.1)

	end
end


UIS.InputBegan:Connect(function(input, gameProccessed)

	if gameProccessed then return end

	if input.KeyCode == Enum.KeyCode.W then
		wHold = true
	end


	if input.KeyCode == Enum.KeyCode.LeftShift and wHold then

		shiftHold = true
		local HoldTime  = 0
		local stamina = plr:GetAttribute("Stamina")
		local lastCycleTime = os.clock()
		
		while shiftHold and wHold do

			print(stamina)

			if stamina <= 0 then
				onShiftRelease()
				break
			end

			stamina = plr:GetAttribute("Stamina")

			plr:SetAttribute("Stamina",math.max(stamina - 1, 0) )

			HoldTime += .1

			local Speed = BaseSpeed * math.exp(SpeedRate * HoldTime)
			Speed = math.clamp(Speed, BaseSpeed, MaxSpeed)
			humanoid.WalkSpeed = Speed

			local delay = 1 / (Speed - BaseSpeed + 1)

			task.wait(delay)
			lastCycleTime = os.clock()
		end
	end
end)

UIS.InputEnded:Connect(function(input)

	if input.KeyCode == Enum.KeyCode.W then
		wHold = false
	end

	if input.KeyCode == Enum.KeyCode.LeftShift then onShiftRelease() end
end)

Try this

2 Likes

This is it, thanks for the reply! Also im pretty confuse about the lastCycleTime that u added.