Repeat Until Loop Not Working When Fired Again

  1. What do you want to achieve? Keep it simple and clear!

I want to make it so that when I touch a part, the player is added to a table and a GUI is cloned and parented to the player’s GUI. When a variable is set to True, they then are able to click a TextButton to leave the table. The player should be able to touch the part after leaving and be able to click the button in order to leave again.

  1. What is the issue? Include screenshots / videos if possible!

When the player leaves, the GUI doesn’t show up when touching the part again.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I tested my script with print() statements in multiple places. I found out that the variable was changed to true, but the repeat until loop did not detect it/didn’t work the second time around. I looked through around a hundred DevForum posts on repeat until loops not working, but was unable to find a solution.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

Here is a video of what happens:

Server Script:

local door = script.Parent
local MaxPlrs = 0
local teleportPart = door.teleportPart

local rps = game:GetService("ReplicatedStorage")
local camEvent = rps:WaitForChild("CameraEvent")

local playersTelporting = {}
local countdown = 15
local tps = game:GetService("TeleportService")
local placeId = 12843002487
local loadgui = game.StarterGui.LoadGui
local teleported = false
local tpevent = rps.TeleportEvent

local camera = game.Workspace.Camera
local campart = door.cameraFocus

local leavegui = game.StarterGui.leave
local playerNamesTp = {}
local Players = game:GetService("Players")
local leaveEvent = rps.LeaveEvent

local debounce = false

local finished = false

door.Touched:Connect(function(hit)
	
	if hit.Parent:FindFirstChild("Humanoid") and  MaxPlrs < 7 then
		if not debounce then
			debounce = true
		
		local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
		
		if plr then
			
			countdown = 15
			MaxPlrs += 1
			
			if playersTelporting[plr] then
				print(plr.Name.." joined.")
			else
				playersTelporting[plr] = true
				table.insert(playersTelporting, plr)
				wait()
					print(plr.Name.." joined.")
			end
			
			plr = plr
			
			local hmr = hit.Parent.HumanoidRootPart
			
			hit.Parent.HumanoidRootPart.CFrame = teleportPart.CFrame
			debounce = false
			
			camEvent:FireClient(plr, teleported, playersTelporting, placeId, loadgui, leavegui, MaxPlrs, finished)
			
			tpevent:FireClient(plr, teleported, playersTelporting, placeId, loadgui)
			
			leaveEvent.OnServerEvent:Connect(function(player, playerLeft)
				MaxPlrs -= 1
				while true do
					if MaxPlrs == 0 then
						print("Everyone left.")
						countdown = 15
						countdown = 15
						finished = false
						print(countdown)
						return
					end
					
					wait()
				end
				finished = false
				print(finished)
				countdown = nil
				local leavePart = door:FindFirstChild("teleportOut")
				hmr.CFrame = leavePart.CFrame
				print(countdown)
				print(playersTelporting)
				
			end)

		end
	debounce = false
			
		end
	else return		
	end
finished = true
end)

repeat wait() until finished == true

while true do
	wait()
	
	if finished == true then
		print(countdown)
		while finished == true and countdown ~= 0 do
			wait(1)
			countdown -= 1
			print(countdown)
		end
		
		if finished == true and MaxPlrs~= 0 then
			print(MaxPlrs)
		table.clone(playersTelporting)
		for _, plr in ipairs(playersTelporting) do
			local newGui = loadgui:Clone()
			newGui.Parent = plr.PlayerGui
			newGui.Enabled = true

			wait(3)

				tps:SetTeleportGui(loadgui)
				local accessCode = tps:ReserveServer(placeId)
				tps:TeleportToPrivateServer(placeId, accessCode, playersTelporting, "SpawnPoint", countdown, loadgui)
				print("got tp")
				playersTelporting[plr] = nil 
				table:clear(playersTelporting)
				countdown = 15
				MaxPlrs = 0
			end

			return
		
		end
	end
	
	if finished ~= true then
		countdown = 15
	end
	
end

Local Script::

local camera = game.Workspace.Camera
local campart = workspace.loadOne.cameraFocus
local rps = game:GetService("ReplicatedStorage")
local camEvent = rps.CameraEvent
local leftEvent = rps.LeaveEvent

playersTeleporting = {}
local teleported = nil
local placeid = nil
local leavegui = nil
local leavecam = workspace.loadOne.cameraLeave
local playerLeft = false
local MaxPlayers = nil
local done = nil

finished = false


camEvent.OnClientEvent:Connect(function(tpd, plrsInLobby, placeId, loadgui, leaveGui, mxplrs, fin)
	MaxPlayers = mxplrs
	teleported = tpd
	playersTeleporting = plrsInLobby
	placeid = placeId
	leavegui = leaveGui
	done = fin
	
	camera.CameraType = Enum.CameraType.Scriptable
	local camera = workspace.CurrentCamera
	local focus = campart
	repeat
		wait()
		camera.CameraType = Enum.CameraType.Scriptable
	until camera.CameraType == Enum.CameraType.Scriptable
	camera.CFrame = focus.CFrame

finished = true

end)

repeat wait() until finished == true -- this is the repeat loop that doesn't fire the second time.


table.clone(playersTeleporting)
for _, plr in ipairs(playersTeleporting) do
	newGui = leavegui:Clone()
	newGui.Parent = plr.PlayerGui
	newGui.Enabled = true
	leavebtn = newGui.Frame.TextButton
	newGui.Enabled = true

end

leavebtn.MouseButton1Click:Connect(function(player)
	newGui.Enabled = false
	wait()
	table.remove(playersTeleporting, player)
	print(playersTeleporting)
	camera.CFrame = leavecam.CFrame
	camera.CameraType = Enum.CameraType.Custom
	playerLeft = true
	finished = false
	print(finished)
	done = false
	print(playersTeleporting)
	leftEvent:FireServer(playerLeft)
end)

Thanks in advance!

1 Like

From what I can see in this following snippet from your LocalScript:

It seems like this section is only running once, as you didn’t connect this to any sort of event. So after the LocalScript runs the whole code successfully, it just only starts to listen to the camEvent event.

I’m not really sure why you want to clone the GUI and parent it instead of just leaving the GUI in StarterGui. But anyways, I’ve helped rewritten your camEvent function:


local camera = game.Workspace.Camera
local campart = workspace.loadOne.cameraFocus
local rps = game:GetService("ReplicatedStorage")
local camEvent = rps.CameraEvent
local leftEvent = rps.LeaveEvent

playersTeleporting = {}
local teleported = nil
local placeid = nil
local leavegui = nil
local leavecam = workspace.loadOne.cameraLeave
local playerLeft = false
local MaxPlayers = nil
local done = nil

finished = false


camEvent.OnClientEvent:Connect(function(tpd, plrsInLobby, placeId, loadgui, leaveGui, mxplrs, fin)
	MaxPlayers = mxplrs
	teleported = tpd
	playersTeleporting = plrsInLobby
	placeid = placeId
	leavegui = leaveGui
	done = fin
	
	camera.CameraType = Enum.CameraType.Scriptable
	local camera = workspace.CurrentCamera
	local focus = campart
	repeat
		wait()
		camera.CameraType = Enum.CameraType.Scriptable
	until camera.CameraType == Enum.CameraType.Scriptable
	camera.CFrame = focus.CFrame

    local checkforLeaveGui = teleported.PlayerGui:FindFirstChild[leavegui.Name]

    if not checkforLeaveGui then
    newGui = leavegui:Clone()
	newGui.Parent = teleported.PlayerGui
     newGui.Enabled = true
	leavebtn = newGui.Frame.TextButton
	newGui.Enabled = true
    else
     checkforLeaveGui.Enabled = true
     leavebtn = newGui.Frame.TextButton
     newGui.Enabled = true
    end
	
true

finished = true

end)

leavebtn.MouseButton1Click:Connect(function(player)
	newGui.Enabled = false
	wait()
	table.remove(playersTeleporting, player)
	print(playersTeleporting)
	camera.CFrame = leavecam.CFrame
	camera.CameraType = Enum.CameraType.Custom
	playerLeft = true
	finished = false
	print(finished)
	done = false
	print(playersTeleporting)
	leftEvent:FireServer(playerLeft)
end)

1 Like

Why don’t you just put the while true loop at the end of the touched event I don’t understand why you would need to use repeat task.wait() until finished == true when you could simply put it after you set it to true, also your while loop does not stop and continues the countdown that’s why your Gui is not appearing the second time, you need to put it in a coroutine and cancel the routine when the player leaves.

Yeah I noticed that to, although the script is kinda hard to read for me since a lot of stuff is spaced out but I think that’s the cause, it seems like the while loops are running forever.

2 Likes

When I touch the part, this error displays in the output:

How would I go about doing that? And what is a coroutine? Thanks for your patience!

I modified the script to your recommendation to put the for loop in the camEvent. This allowed it to work as many times as I like, because it is now attached to a RemoteEvent. Thank you for your help!

Below I have attached the script I used.

local camera = game.Workspace.Camera
local campart = workspace.loadOne.cameraFocus
local rps = game:GetService("ReplicatedStorage")
local camEvent = rps.CameraEvent
local leftEvent = rps.LeaveEvent

playersTeleporting = {}
local teleported = nil
local placeid = nil
local leavegui = nil
local leavecam = workspace.loadOne.cameraLeave
local playerLeft = false
local MaxPlayers = nil
local done = nil
local hmr = nil
local teleportout = nil

finished = false


camEvent.OnClientEvent:Connect(function(tpd, plrsInLobby, placeId, loadgui, leaveGui, mxplrs, fin, humpart, tpout)
	MaxPlayers = mxplrs
	teleported = tpd
	playersTeleporting = plrsInLobby
	placeid = placeId
	leavegui = leaveGui
	done = fin
	hmr = humpart
	teleportout = tpout

	camera.CameraType = Enum.CameraType.Scriptable
	local camera = workspace.CurrentCamera
	local focus = campart
	repeat
		wait()
		camera.CameraType = Enum.CameraType.Scriptable
	until camera.CameraType == Enum.CameraType.Scriptable
	camera.CFrame = focus.CFrame

	finished = true
	
	repeat task.wait() until finished == true

	table.clone(playersTeleporting)
	for _, plr in ipairs(playersTeleporting) do
		
		local leavegui = plr.PlayerGui.leave
		leavebtn = leavegui.leave.TextButton
		leavegui.Enabled = true
		
		
	end
	
	leavebtn.MouseButton1Click:Connect(function(player)
		leavebtn.Parent.Parent.Enabled = false
		wait()
		table.remove(playersTeleporting, player)
		camera.CFrame = leavecam.CFrame
		camera.CameraType = Enum.CameraType.Custom
		playerLeft = true
		finished = false
		done = false
		hmr.CFrame = teleportout.CFrame
		leftEvent:FireServer(playerLeft)
	end)
	
end)
2 Likes