I currently have a timer system for each induvial player. The timer system involves a GUI on the players screen.
What do you want to achieve? Keep it simple and clear!
I am trying to make it where if the local player dies, their timer will reset.
What is the issue? Include screenshots / videos if possible!
Whenever the player dies, their timer does reset but it counts down 2x as fast. It should only count down by 1 every second.
Here is a video of the issue I am having:
And here is the code that I have which is a local script in StarterPlayerScripts:
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("OneMinuteTimer")
local remoteEvent2 = ReplicatedStorage:WaitForChild("StopTimer")
local Checkpoint = workspace:WaitForChild("Checkpoints")
local lastCheckpointTouched = nil
local heart = "rbxassetid://13841443245"
local skull = "rbxassetid://13841410348"
local clonedgui = Player.PlayerGui:WaitForChild("Timer")
local timerTime = 2 * 60
local Started = false
local mode = false
local running = false
local red = Color3.fromRGB(231, 37, 37)
local black = Color3.fromRGB(0,0,0)
local white = Color3.fromRGB(255, 255, 255)
local green1 = Color3.fromRGB(80, 207, 61)
local timersound = game.ReplicatedStorage.TimerSound
local function ResetTimer()
wait()
if running == false then
running = true
StartTimer()
end
if lastCheckpointTouched and lastCheckpointTouched.TimeValue then
if lastCheckpointTouched.TimeValue.Value == 1 then
timerTime = 1 * 60
elseif lastCheckpointTouched.TimeValue.Value == 2 then
timerTime = 45
elseif lastCheckpointTouched.TimeValue.Value == 3 then
timerTime = 30
else
print("Hi - Unknown Checkpoint Value")
end
if not Started then
Started = true
task.spawn(StartTimer)
else
Player.CharacterAdded:Wait()
timerTime = timerTime
end
end
end
local function changeColour()
if clonedgui.Frame.TextLabel.TextColor3 == red and clonedgui.Frame.TextLabel.UIStroke.Color == black then
clonedgui.Frame.TextLabel.TextColor3 = green1
clonedgui.Frame.TextLabel.UIStroke.Color = black
end
end
function StartTimer()
while timerTime > 0 and running == true do
timerTime = timerTime - 1
timerTime = math.max(0, timerTime)
local minutes = math.floor(timerTime / 60)
local text = string.format("%d:%02d", minutes, timerTime % 60)
clonedgui.Frame.TextLabel.Text = text
if minutes <= 0 and timerTime <= 10 and timerTime >= 9.5 then
clonedgui.Frame.TextLabel.TextColor3 = red
clonedgui.Frame.TextLabel.UIStroke.Color = black
timersound:Play()
end
if timerTime <= 0 then
if mode == false then
print(mode)
else
print(mode)
Player.Character.Humanoid.Health = 0
end
end
wait(1)
Player.Character:WaitForChild("Humanoid").Died:Connect(function()
ResetTimer()
end)
end
end
remoteEvent.OnClientEvent:Connect(function(checkpointPart)
changeColour()
if checkpointPart and checkpointPart:IsA("BasePart") then
if lastCheckpointTouched ~= checkpointPart then
lastCheckpointTouched = checkpointPart
print(lastCheckpointTouched.TimeValue.Value)
if lastCheckpointTouched.TimeValue.Value == 1 then
timerTime = 1 * 60
elseif lastCheckpointTouched.TimeValue.Value == 2 then
timerTime = 45
elseif lastCheckpointTouched.TimeValue.Value == 3 then
timerTime = 30
else
print("Hi - Unknown Checkpoint Value")
end
local image = clonedgui.image.modeimage
if lastCheckpointTouched.Mode.Value == true then
mode = true
image.Image = skull
else
image.Image = heart
mode = false
end
changeColour()
ResetTimer()
end
end
end)
local function stoptimer()
running = false
clonedgui.Frame.TextLabel.Text = "0:00"
lastCheckpointTouched = nil
end
remoteEvent2.OnClientEvent:Connect(stoptimer)
Every time you die your script runs again so just break the loop when the player dies you can create a debounce for that
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("OneMinuteTimer")
local remoteEvent2 = ReplicatedStorage:WaitForChild("StopTimer")
local Checkpoint = workspace:WaitForChild("Checkpoints")
local lastCheckpointTouched = nil
local heart = "rbxassetid://13841443245"
local skull = "rbxassetid://13841410348"
local clonedgui = Player.PlayerGui:WaitForChild("Timer")
local timerTime = 2 * 60
local Started = false
local mode = false
local running = false
local died = false
local red = Color3.fromRGB(231, 37, 37)
local black = Color3.fromRGB(0,0,0)
local white = Color3.fromRGB(255, 255, 255)
local green1 = Color3.fromRGB(80, 207, 61)
local timersound = game.ReplicatedStorage.TimerSound
local function ResetTimer()
wait()
if running == false then
running = true
StartTimer()
end
if lastCheckpointTouched and lastCheckpointTouched.TimeValue then
if lastCheckpointTouched.TimeValue.Value == 1 then
timerTime = 1 * 60
elseif lastCheckpointTouched.TimeValue.Value == 2 then
timerTime = 45
elseif lastCheckpointTouched.TimeValue.Value == 3 then
timerTime = 30
else
print("Hi - Unknown Checkpoint Value")
end
if not Started then
Started = true
task.spawn(StartTimer)
else
Player.CharacterAdded:Wait()
timerTime = timerTime
end
end
end
local function changeColour()
if clonedgui.Frame.TextLabel.TextColor3 == red and clonedgui.Frame.TextLabel.UIStroke.Color == black then
clonedgui.Frame.TextLabel.TextColor3 = green1
clonedgui.Frame.TextLabel.UIStroke.Color = black
end
end
Player.Character:WaitForChild("Humanoid").Died:Connect(function()
died = true
end)
function StartTimer()
while timerTime > 0 and running == true do
if (died) then
break
end
timerTime = timerTime - 1
timerTime = math.max(0, timerTime)
local minutes = math.floor(timerTime / 60)
local text = string.format("%d:%02d", minutes, timerTime % 60)
clonedgui.Frame.TextLabel.Text = text
if minutes <= 0 and timerTime <= 10 and timerTime >= 9.5 then
clonedgui.Frame.TextLabel.TextColor3 = red
clonedgui.Frame.TextLabel.UIStroke.Color = black
timersound:Play()
end
if timerTime <= 0 then
if mode == false then
print(mode)
else
print(mode)
Player.Character.Humanoid.Health = 0
end
end
wait(1)
Player.Character:WaitForChild("Humanoid").Died:Connect(function()
ResetTimer()
end)
end
end
remoteEvent.OnClientEvent:Connect(function(checkpointPart)
changeColour()
if checkpointPart and checkpointPart:IsA("BasePart") then
if lastCheckpointTouched ~= checkpointPart then
lastCheckpointTouched = checkpointPart
print(lastCheckpointTouched.TimeValue.Value)
if lastCheckpointTouched.TimeValue.Value == 1 then
timerTime = 1 * 60
elseif lastCheckpointTouched.TimeValue.Value == 2 then
timerTime = 45
elseif lastCheckpointTouched.TimeValue.Value == 3 then
timerTime = 30
else
print("Hi - Unknown Checkpoint Value")
end
local image = clonedgui.image.modeimage
if lastCheckpointTouched.Mode.Value == true then
mode = true
image.Image = skull
else
image.Image = heart
mode = false
end
changeColour()
ResetTimer()
end
end
end)
local function stoptimer()
running = false
clonedgui.Frame.TextLabel.Text = "0:00"
lastCheckpointTouched = nil
end
remoteEvent2.OnClientEvent:Connect(stoptimer)
Thanks for the response. It is giving me an error âPlayers.naderbocker2.PlayerScripts.LocalScript:82: attempt to index nil with âWaitForChildââ
First, you shouldnât create a WaitForChild inside a loop, and secondly, you donât need to catch the player.Died event, because it can be executed only once per script, and I donât recommend putting it inside a loop, because it it will always be storing it and then when you die it will run everything at once.
Just create this event outside of a loop creating a debounce of âdiedâ, and check if it dies, if it dies just break and reset as if it were an event inside it
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("OneMinuteTimer")
local remoteEvent2 = ReplicatedStorage:WaitForChild("StopTimer")
local Checkpoint = workspace:WaitForChild("Checkpoints")
local lastCheckpointTouched = nil
local heart = "rbxassetid://13841443245"
local skull = "rbxassetid://13841410348"
local clonedgui = Player.PlayerGui:WaitForChild("Timer")
local timerTime = 2 * 60
local Started = false
local mode = false
local running = false
local died = false
local red = Color3.fromRGB(231, 37, 37)
local black = Color3.fromRGB(0,0,0)
local white = Color3.fromRGB(255, 255, 255)
local green1 = Color3.fromRGB(80, 207, 61)
local timersound = game.ReplicatedStorage.TimerSound
local function ResetTimer()
wait()
if running == false then
running = true
StartTimer()
end
if lastCheckpointTouched and lastCheckpointTouched.TimeValue then
if lastCheckpointTouched.TimeValue.Value == 1 then
timerTime = 1 * 60
elseif lastCheckpointTouched.TimeValue.Value == 2 then
timerTime = 45
elseif lastCheckpointTouched.TimeValue.Value == 3 then
timerTime = 30
else
print("Hi - Unknown Checkpoint Value")
end
if not Started then
Started = true
task.spawn(StartTimer)
else
Player.CharacterAdded:Wait()
timerTime = timerTime
end
end
end
local function changeColour()
if clonedgui.Frame.TextLabel.TextColor3 == red and clonedgui.Frame.TextLabel.UIStroke.Color == black then
clonedgui.Frame.TextLabel.TextColor3 = green1
clonedgui.Frame.TextLabel.UIStroke.Color = black
end
end
Player.Character:FindFirstChildOfClass("Humanoid").Died:Connect(function()
died = true
end)
function StartTimer()
while timerTime > 0 and running == true do
if (died) then
ResetTimer()
break
end
timerTime = timerTime - 1
timerTime = math.max(0, timerTime)
local minutes = math.floor(timerTime / 60)
local text = string.format("%d:%02d", minutes, timerTime % 60)
clonedgui.Frame.TextLabel.Text = text
if minutes <= 0 and timerTime <= 10 and timerTime >= 9.5 then
clonedgui.Frame.TextLabel.TextColor3 = red
clonedgui.Frame.TextLabel.UIStroke.Color = black
timersound:Play()
end
if timerTime <= 0 then
if mode == false then
print(mode)
else
print(mode)
Player.Character.Humanoid.Health = 0
end
end
end
end
remoteEvent.OnClientEvent:Connect(function(checkpointPart)
changeColour()
if checkpointPart and checkpointPart:IsA("BasePart") then
if lastCheckpointTouched ~= checkpointPart then
lastCheckpointTouched = checkpointPart
print(lastCheckpointTouched.TimeValue.Value)
if lastCheckpointTouched.TimeValue.Value == 1 then
timerTime = 1 * 60
elseif lastCheckpointTouched.TimeValue.Value == 2 then
timerTime = 45
elseif lastCheckpointTouched.TimeValue.Value == 3 then
timerTime = 30
else
print("Hi - Unknown Checkpoint Value")
end
local image = clonedgui.image.modeimage
if lastCheckpointTouched.Mode.Value == true then
mode = true
image.Image = skull
else
image.Image = heart
mode = false
end
changeColour()
ResetTimer()
end
end
end)
local function stoptimer()
running = false
clonedgui.Frame.TextLabel.Text = "0:00"
lastCheckpointTouched = nil
end
remoteEvent2.OnClientEvent:Connect(stoptimer)
it seems that the issue lies in the ResetTimer function. Currently, you have a line that sets the timerTime variable to the checkpoint value, but then immediately sets it again to itself without any change
This redundant line does not have any effect on the timer. To fix the issue and ensure that the timer counts down by 1 every second after resetting, you need to remove that line from the ResetTimer function.
local function ResetTimer()
wait()
if running == false then
running = true
StartTimer()
end
if lastCheckpointTouched and lastCheckpointTouched.TimeValue then
if lastCheckpointTouched.TimeValue.Value == 1 then
timerTime = 1 * 60
elseif lastCheckpointTouched.TimeValue.Value == 2 then
timerTime = 45
elseif lastCheckpointTouched.TimeValue.Value == 3 then
timerTime = 30
else
print("Hi - Unknown Checkpoint Value")
end
if not Started then
Started = true
task.spawn(StartTimer)
end
end
end
Put it in the TextLabel without the ResetOnSpawn on, otherwise, if you keep dying over and over again, the text will count as a negative time, and you donât want that.
It is necessarily needed to have a Screengui, a textlabel and more if you want to (since you already have it, but forgot to add it into the original game, meaning you added it with a script).
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("OneMinuteTimer")
local remoteEvent2 = ReplicatedStorage:WaitForChild("StopTimer")
local Checkpoint = workspace:WaitForChild("Checkpoints")
local lastCheckpointTouched = nil
local heart = "rbxassetid://13841443245"
local skull = "rbxassetid://13841410348"
local clonedgui = Player.PlayerGui:WaitForChild("Timer")
local timerTime = 2 * 60
local Started = false
local mode = false
local running = false
local red = Color3.fromRGB(231, 37, 37)
local black = Color3.fromRGB(0,0,0)
local white = Color3.fromRGB(255, 255, 255)
local green1 = Color3.fromRGB(80, 207, 61)
local timersound = game.ReplicatedStorage.TimerSound
local function ResetTimer()
wait()
if running == false then
running = true
StartTimer()
end
if lastCheckpointTouched and lastCheckpointTouched.TimeValue then
if lastCheckpointTouched.TimeValue.Value == 1 then
timerTime = 1 * 60
elseif lastCheckpointTouched.TimeValue.Value == 2 then
timerTime = 45
elseif lastCheckpointTouched.TimeValue.Value == 3 then
timerTime = 30
else
print("Hi - Unknown Checkpoint Value")
end
if not Started then
Started = true
task.spawn(StartTimer)
else
Player.CharacterAdded:Wait()
timerTime = timerTime
end
end
end
local function changeColour()
if clonedgui.Frame.TextLabel.TextColor3 == red and clonedgui.Frame.TextLabel.UIStroke.Color == black then
clonedgui.Frame.TextLabel.TextColor3 = green1
clonedgui.Frame.TextLabel.UIStroke.Color = black
end
end
function StartTimer()
while timerTime > 0 and running == true do
timerTime = timerTime - 1
timerTime = math.max(0, timerTime)
local minutes = math.floor(timerTime / 60)
local text = string.format("%d:%02d", minutes, timerTime % 60)
clonedgui.Frame.TextLabel.Text = text
if minutes <= 0 and timerTime <= 10 and timerTime >= 9.5 then
clonedgui.Frame.TextLabel.TextColor3 = red
clonedgui.Frame.TextLabel.UIStroke.Color = black
timersound:Play()
end
if timerTime <= 0 then
if mode == false then
print(mode)
else
print(mode)
Player.Character.Humanoid.Health = 0
end
end
wait(1)
Player.Character:WaitForChild("Humanoid").Died:Connect(function()
ResetTimer()
timerTime += 1
end)
end
end
remoteEvent.OnClientEvent:Connect(function(checkpointPart)
changeColour()
if checkpointPart and checkpointPart:IsA("BasePart") then
if lastCheckpointTouched ~= checkpointPart then
lastCheckpointTouched = checkpointPart
print(lastCheckpointTouched.TimeValue.Value)
if lastCheckpointTouched.TimeValue.Value == 1 then
timerTime = 1 * 60
elseif lastCheckpointTouched.TimeValue.Value == 2 then
timerTime = 45
elseif lastCheckpointTouched.TimeValue.Value == 3 then
timerTime = 30
else
print("Hi - Unknown Checkpoint Value")
end
local image = clonedgui.image.modeimage
if lastCheckpointTouched.Mode.Value == true then
mode = true
image.Image = skull
else
image.Image = heart
mode = false
end
changeColour()
ResetTimer()
end
end
end)
local function stoptimer()
running = false
clonedgui.Frame.TextLabel.Text = "0:00"
lastCheckpointTouched = nil
end
remoteEvent2.OnClientEvent:Connect(stoptimer)
Youâre right, the line if running == false then in the ResetTimer function could be causing the issue
local function ResetTimer()
wait()
running = true
StartTimer()
if lastCheckpointTouched and lastCheckpointTouched.TimeValue then
if lastCheckpointTouched.TimeValue.Value == 1 then
timerTime = 1 * 60
elseif lastCheckpointTouched.TimeValue.Value == 2 then
timerTime = 45
elseif lastCheckpointTouched.TimeValue.Value == 3 then
timerTime = 30
else
print("Hi - Unknown Checkpoint Value")
end
if not Started then
Started = true
task.spawn(StartTimer)
end
end
end
No it doesnât actually look like that fixed the problem, now when the player dies or resets the timer restarts but is counting down by 4 seconds at the same 2x pace.
The timer GUI is being cloned to every players PlayerGui as soon as they join the game. The timer GUI is in Replicated Storage, should I still put the script you provided in the timer GUI?
The issue with the timer counting down 2x as fast when the local player dies can be resolved by restructuring the code. Currently, the StartTimer function is being called multiple times, which leads to unexpected behavior.
To fix this, you can modify the code as follows:
local function ResetTimer()
if running == false then
running = true
StartTimer()
end
-- Rest of the code...
end
function StartTimer()
-- Move the Player.Character:WaitForChild("Humanoid").Died connection outside the while loop
Player.Character:WaitForChild("Humanoid").Died:Connect(function()
ResetTimer()
end)
while timerTime > 0 and running == true do
-- Rest of the code...
end
end
By moving the Player.Character:WaitForChild("Humanoid").Died connection outside the while loop in the StartTimer function, it ensures that the connection is established only once. This prevents the timer from counting down 2x as fast when the player dies.