so this script is a countdown gui, but I only want it to count when the “TeamSelectFrame” is visible. this is my script:
local Timer = game.StarterGui.ScreenGui2.TeamSelectFrame.Timer
function CountdownBySeconds(number)
local Time = Instance.new(“IntValue”,script.Parent)
Time.Value = number
Time.Name = “Time”
while wait(1) do
Time.Value = Time.Value-1
script.Parent.Timer.Text = Time.Value
if script.Parent.Parent.TeamSelectFrame.Visible == false then
Time.Value = 30
if script.Parent.Parent.TeamSelectFrame.Visible == true then
Time.Value = Time.Value - 1
script.Parent.Timer.Text = Time.Value
if Time.Value == 0 or Time.Value<0 then
wait(.1)
script.Parent.Parent.TeamSelectFrame.Visible = false
end
end
end
end
end
CountdownBySeconds(30)
for some reason it is just stuck or when it’s not stuck it just keeps counting even when the frames invisible, and I can’t figure it out.
You are using very complex solutions to certain things. Try this:
local Time
local TeamSelectFrame --enter the location to the teamselectframe
function CountdownBySeconds(number)
Time = number
for i=1,number do
script.Parent.Text = Time
Time = Time - 1
wait(1)
end
end
TeamSelectFrame.Changed:connect(function()
if TeamSelectFrame.Visible == true then
CountdownBySeconds(30)
end
end)
The reason it’s running indefinitely is because you’re using a while loop in your function. Your script is also inefficient and unnecessarily long. Maybe try this instead:
-- LocalScript inside of the ScreenGui
local label = -- path to your TextLabel for the countdown text
local frame = -- path to your frame that you check if it's visible or not
local function Countdown(duration)
for i = duration, 0, -1 do
if frame.Visible == false then break end
label.Text = i
wait(1)
end
frame.Visible = false
end
Countdown(30)
function CountdownBySeconds(number) – number = 30
local Time = Instance.new(“IntValue”,script.Parent)
Time.Value = number
if script.Parent.Parent.TeamSelectFrame.Visible == false then
return
end
for i = number, 0, -1 do
script.Parent.Timer.Text = i
end
if Time.Value == 0 or Time.Value <= 0 then
wait(0.1)
script.Parent.Parent.TeamSelectFrame.Visible = false
end
end
I went and rewrote your script - added comments to clarify what does what and why.
In a nutshell: uses GetPropertyChangedSignal for the TeamSelectFrame, and Changed for the Timer. Debounce added to prevent the code from firing multiple times.
local TeamSelectFrame = script.Parent.Parent.TeamSelectFrame -- Define TeamSelectFrame to a variable
local TimerTxt = script.Parent.Timer -- Define Timer to a variable
local CountingDown = false -- Have a sort of debounce to prevent multiple executions
local Time = Instance.new("IntValue") -- The IntValue timer
Time.Name = "Time"
Time.Parent = script.Parent
TeamSelectFrame:GetPropertyChangedSignal("Visible"):Connect(function() -- Listen for when the Visible property changes
if TeamSelectFrame.Visible and not CountingDown then -- Is it visible? And can we execute the following?
CountingDown = true -- Prevent multiple from executing
for Count = 30, 1, -1 do -- Count down the timer
Time.Value = Count -- Set the IntValue's value to the Count variable
wait(1) -- Sleep for 1 second
if not TeamSelectFrame.Visible then -- If the frame became not visible, then
break -- break the for loop
end
end
TeamSelectFrame.Visible = false -- Set the visibility back to false
end
end)
Time.Changed:Connect(function() -- Listen for when the Time IntValue's value property changes
TimerTxt.Text = tostring(Time.Value) -- Set TimerTxt's text property to Time IntValue's value
end)
I hope this helped. If you have any questions, please don’t hesitate to ask.
EDIT
I kept the IntValue just in case it serves purpose with another script the OP uses - the rewritten code doesn’t create multiple new ones upon exectution either, it creates the one and utilizes it within the code. ;p
I still don’t get why you would need to create a whole new IntValue object when you could just use 1 variable. Wouldn’t there be a lot of copies each time you called the function?