Os.clock() timer

Hello, im trying to make a timer for my game so that if you die 3 times, you have to wait 2 minutes, but it goes down an extra seconds in the negatives and doesnt start from what i set it to

code:

--//Variables
local Counter = 0
local ObbySpawn = workspace.Spawns:WaitForChild("ObbySpawner")
local ObbyBlock = workspace:WaitForChild("Map"):WaitForChild("ObbyBlocker")
local Part = script.Parent
local DefaultSpawnLocation = workspace:WaitForChild("Spawns"):WaitForChild("DefaultSpawnLocation")

local connection

local SurfaceGui = script:WaitForChild("SurfaceGui")
local plr = game:GetService("Players").LocalPlayer
local plrGui = plr:WaitForChild("PlayerGui")

local TimerLabel = SurfaceGui.TextLabel

local deadline = os.clock() + 10 -- 2 Minutes

local debounce = false

--//Functions

function UpdateTimer()
	local timerFormat = "%d:%d" -- As long it has the "%d", it will be possible to replace them with numbers.
	-- Assuming this is inside of a BindToRenderStep or Updater.
	local remaining = deadline - os.clock()
	local m = math.floor(remaining/60) -- Minutes
	local s = math.floor(remaining%60) -- Seconds -- Milliseconds

	TimerLabel.Text = "Retry in: " .. string.format(timerFormat,m,s)
end

function onTouched(Hit)
	if debounce == false then
		debounce = true
		if Hit.Parent:FindFirstChild("Humanoid") then
			local Char = Hit.Parent
			if Counter <= 3  then
				Char:MoveTo(ObbySpawn.Position + Vector3.new(0,5,0))
				Counter += 1
			elseif Counter > 3 then
				Char:MoveTo(DefaultSpawnLocation.Position + Vector3.new(0,5,0))
				ObbyBlock.Transparency = 0.5
				ObbyBlock.CanCollide = true
				
				SurfaceGui.Adornee = ObbyBlock
				
				UpdateTimer()
				task.wait()
				connection = game:GetService("RunService").RenderStepped:Connect(UpdateTimer) -- Connect to RenderStepped so we can update every frame.

				task.wait(10)
				--disconnect renderstepped
				connection:Disconnect()
				--destroy gui
				SurfaceGui.Adornee = nil
				deadline = os.clock() + 10
				
				ObbyBlock.Transparency = 1
				ObbyBlock.CanCollide = false

				Counter = 0
			end
			task.wait()
			debounce = false
		end
	end
end

Part.Touched:Connect(onTouched)

Idk, I would recommend not to use os.clock() in your timer script, since it automatically pulls the current time from your machine. I would recommend making a variable that keeps a static time and counts down from there.

I would use os.time instead of os.clock, because os.clock is meant for benchmarking and not for actual game functionality.

Code:

--//Variables
local SurfaceGui = script:WaitForChild("SurfaceGui")
local plr = game:GetService("Players").LocalPlayer
local plrGui = plr:WaitForChild("PlayerGui")
local TimerLabel = SurfaceGui.TextLabel
local ObbySpawn = workspace.Spawns:WaitForChild("ObbySpawner")
local ObbyBlock = workspace:WaitForChild("Map"):WaitForChild("ObbyBlocker")
local Part = script.Parent
local DefaultSpawnLocation = workspace:WaitForChild("Spawns"):WaitForChild("DefaultSpawnLocation")

--//Controls
local Counter = 0
local connection = nil
local deadline = os.time() + 120 -- 2 Minutes
local debounce = false

--//Functions
local function UpdateTimer()
	local timerFormat = "%d:%d" -- As long it has the "%d", it will be possible to replace them with numbers.
	-- Assuming this is inside of a BindToRenderStep or Updater.
	local remaining = deadline - os.time()
	local m = math.floor(remaining/60) -- Minutes
	local s = math.floor(remaining%60) -- Seconds -- Milliseconds

	TimerLabel.Text = "Retry in: " .. string.format(timerFormat,m,s)
end

local function onTouched(Hit)
	if debounce == false then
		debounce = true
		if Hit.Parent:FindFirstChild("Humanoid") then
			local Char = Hit.Parent
			
			if Counter <= 3  then
				Char:MoveTo(ObbySpawn.Position + Vector3.new(0,5,0))
				Counter += 1
			elseif Counter > 3 then
				Char:MoveTo(DefaultSpawnLocation.Position + Vector3.new(0,5,0))
				ObbyBlock.Transparency = 0.5
				ObbyBlock.CanCollide = true

				SurfaceGui.Adornee = ObbyBlock

				UpdateTimer()
				task.wait()
				connection = game:GetService("RunService").RenderStepped:Connect(UpdateTimer) -- Connect to RenderStepped so we can update every frame.

				task.wait(10)
				--disconnect renderstepped
				connection:Disconnect()
				--destroy gui
				SurfaceGui.Adornee = nil
				deadline = os.time() + 120

				ObbyBlock.Transparency = 1
				ObbyBlock.CanCollide = false

				Counter = 0
			end
			
			task.wait()
			debounce = false
		end
	end
end

Part.Touched:Connect(onTouched)

still, i put it at 10 seconds for testing, it started at 5, ended at -1:55

I tried this code, I did it so it ends after ten seconds of running, but i made it print the time, these are the results
image

Try using a while loop to count until there is no more time.

Code:

--//Services
local Players = 	game:GetService("Players")

--//Variables
local plr = Players.LocalPlayer
local plrGui = plr:WaitForChild("PlayerGui")
local DefaultSpawnLocation = workspace:WaitForChild("Spawns"):WaitForChild("DefaultSpawnLocation")
local ObbySpawn = workspace.Spawns:WaitForChild("ObbySpawner")
local ObbyBlock = workspace:WaitForChild("Map"):WaitForChild("ObbyBlocker")
local Part = script.Parent
local SurfaceGui = script:WaitForChild("SurfaceGui")
local TimerLabel = SurfaceGui.TextLabel

--//Controls
local Counter = 0
local timeRemaining = 10
local debounce = false

--//Functions
local function UpdateTimer(deltaTime)
	timeRemaining -= deltaTime
	
	local m = math.floor(timeRemaining/60) -- Minutes
	local s = math.floor(timeRemaining%60) -- Seconds -- Milliseconds

	TimerLabel.Text = "Retry in: " .. string.format("%d:%d", m, s)
end

local function onTouched(Hit)
	if debounce then
		return
	end
	
	debounce = true
	
	local Char = Hit.Parent
	
	if Char:FindFirstChild("Humanoid") then
		if Counter <= 3  then
			Char:MoveTo(ObbySpawn.Position + Vector3.new(0,5,0))
			Counter += 1
		elseif Counter > 3 then
			Char:MoveTo(DefaultSpawnLocation.Position + Vector3.new(0,5,0))
			ObbyBlock.Transparency = 0.5
			ObbyBlock.CanCollide = true

			SurfaceGui.Adornee = ObbyBlock
			
			while timeRemaining > 0 do
				UpdateTimer(task.wait(0.1))
			end

			--destroy gui
			SurfaceGui.Adornee = nil
			timeRemaining = 10

			ObbyBlock.Transparency = 1
			ObbyBlock.CanCollide = false

			Counter = 0
		end
	end
	
	debounce = false
end

Part.Touched:Connect(onTouched)

thank you for saving me twice in one day :pray:

1 Like

No problem lol. Make sure to tweak that task.wait(n) value if it causes too much of a performance loss.
(Increasing wait time = better performance but less accurate, lower wait time = worse performance but more accurate)

ok, noted. thanks a lot again!

1 Like

one more thing, sorry
do you think it would be possible to make the it so if the seconds < 10 it would be 0:09 instead of 0:9?

Yes, you can use %02i to add a 0 in front of values that are only 1 digit.

Code:

--//Services
local Players = game:GetService("Players")

--//Variables
local plr = Players.LocalPlayer
local plrGui = plr:WaitForChild("PlayerGui")
local DefaultSpawnLocation = workspace:WaitForChild("Spawns"):WaitForChild("DefaultSpawnLocation")
local ObbySpawn = workspace.Spawns:WaitForChild("ObbySpawner")
local ObbyBlock = workspace:WaitForChild("Map"):WaitForChild("ObbyBlocker")
local Part = script.Parent
local SurfaceGui = script:WaitForChild("SurfaceGui")
local TimerLabel = SurfaceGui.TextLabel

--//Controls
local Counter = 0
local timeRemaining = 10
local debounce = false

--//Functions
local function UpdateTimer(deltaTime)
	timeRemaining -= deltaTime

	local m = math.floor(timeRemaining/60) -- Minutes
	local s = math.floor(timeRemaining%60) -- Seconds -- Milliseconds

	TimerLabel.Text = "Retry in: " .. string.format("%02i:%02i", m, s)
end

local function onTouched(Hit)
	if debounce then
		return
	end

	debounce = true

	local Char = Hit.Parent

	if Char:FindFirstChild("Humanoid") then
		if Counter <= 3  then
			Char:MoveTo(ObbySpawn.Position + Vector3.new(0,5,0))
			Counter += 1
		elseif Counter > 3 then
			Char:MoveTo(DefaultSpawnLocation.Position + Vector3.new(0,5,0))
			ObbyBlock.Transparency = 0.5
			ObbyBlock.CanCollide = true

			SurfaceGui.Adornee = ObbyBlock

			while timeRemaining > 0 do
				UpdateTimer(task.wait(0.1))
			end

			--destroy gui
			SurfaceGui.Adornee = nil
			timeRemaining = 10

			ObbyBlock.Transparency = 1
			ObbyBlock.CanCollide = false

			Counter = 0
		end
	end

	debounce = false
end

Part.Touched:Connect(onTouched)
1 Like

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