Stop watch Gui script doesn't work

Hi! So I am making a stop watch UI:
When you click the stopwatch button, it starts a 5 second countdown so you can get ready, and then starts the stopwatch when it hits 0. You can cancel the stopwatch in 2 ways: Stepping on a specific part I put in workspace, or you can just hit the button again.

I have two problems:

  1. The “Stop” part doesn’t actually stop the stopwatch
  2. The stopwatch doesn’t work after you stop and restart it.

Here is my script:

local button = script.Parent
local display = script.Parent.Display
local countdownTime = 5
local timer = 0
local countingDown = false
local stopConnection = nil

local function formatTime(time)
    local minutes = math.floor(time / 60)
    local seconds = time - (minutes * 60)
    local milliseconds = math.floor((time % 1) * 1000)
    return string.format("%02d:%02d:%03d", minutes, seconds, milliseconds)
end

button.MouseButton1Click:Connect(function()
    if not countingDown then
        countingDown = true
        button.Text = "Cancel"
        while countdownTime > 0 do
            display.Text = formatTime(countdownTime)
            countdownTime = countdownTime - 1
            wait(1)
            if not countingDown then
                countdownTime = 5
                display.Text = "Ready"
                button.Text = "Start"
                break
            end
        end
        if countingDown then
            display.Text = "00:00:000"
            button.Text = "Stop"
            local stopper = workspace:WaitForChild("Stopper")
            local stopped = false
            stopConnection = stopper.Touched:Connect(function(hit)
                if hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
                    stopped = true
                end
            end)
            while not stopped do
                timer = timer + 1/60
                display.Text = formatTime(timer)
            end
            timer = 0
            display.Text = "Stopped"
            button.Text = "Start"
        end
    else
        countingDown = false
        countdownTime = 5
        timer = 0
        display.Text = "Ready"
        button.Text = "Start"
        if stopConnection then
            stopConnection:Disconnect()
            stopConnection = nil
        end
    end
end)

Thanks!

You would add another connection via :Once so if the same button is clicked it will set stopped to true.

Without a task.wait I your script will stall too, you have to give some time to keep track of

if countingDown then
	display.Text = "00:00:000"
	button.Text = "Stop"
	local stopper = workspace:WaitForChild("Stopper")
	local stopped = false
	stopConnection = stopper.Touched:Connect(function(hit)
		if hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
			stopped = true
		end
	end)
	local cancelConnection = button.MouseButton1Click:Once(function()
		stopped = true
	end)
	
	while not stopped do
		timer = task.wait() -- wait here
		display.Text = formatTime(timer)
	end
	
	timer = 0
	display.Text = "Stopped"
	button.Text = "Start"
	
	if cancelConnection.Connected then
		cancelConnection:Disconnect()
	end
	if stopConnection and stopConnection.Connected then
		stopConnection:Disconnect()
	end
end

Try this script out too, I re-wrote your timer to have one loop on HeartBeat and track everything else by state and get timing by calculating from time()

local button = script.Parent :: TextButton
local display = script.Parent.Display
local countdownTime = 5
local timer = 0
local countingDown = false
local stopConnection = nil

local function formatTime(time)
	local minutes = math.floor(time / 60)
	local seconds = time - (minutes * 60)
	local milliseconds = math.floor((time % 1) * 1000)
	return string.format("%02d:%02d:%03d", minutes, seconds, milliseconds)
end

local state = "Start"

game:GetService("RunService").Heartbeat:Connect(function(delta)
	local t = time()
	if state == "CountDown" then
		local timeRemaining = 5 - (t - timer)
		
		display.Text = formatTime(timeRemaining)
		
		if timeRemaining <= 0 then
			state = "Counting"
			timer = time()
			button.Text = "Stop"
		end
	elseif state == "Counting" then
		local timeElapsed = t - timer
		display.Text = formatTime(timeElapsed)	
	end
end)

button.MouseButton1Click:Connect(function()
	if state == "Start" then
		state = "CountDown"
		timer = time()
		button.Text = "Cancel"
	elseif state == "CountDown" then
		display.Text = "00:00:000"
		state = "Start"
		button.Text = "Start"
	elseif state == "Counting" then
		state = "Start"
		button.Text = "Start"
	end
end)

Alright, this works, although I more meant that when you click the timer it pauses the timer instead of canceling it, and then you can click it again to reset it. Forgive me for my lack of clarification. Thanks for your help!

You could do a break in the loop when that happens, it just stops the loop.
while wait() do
if --parameters then
break
end

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