Help with script

I’m making a timer player limiter teleporter and when you enter the script adds you to a list and when you leave it removes you from the list

but its a bit glitchy

here’s the script

--			SERVICES			--

local Players = game:GetService('Players')
local ts = game:GetService('TeleportService')
local ReplicatedStorage = game:GetService('ReplicatedStorage')

--			 REMOTES			--

local remote1 = ReplicatedStorage:WaitForChild('Remotes'):WaitForChild('JoinLobby')
local remote2 = ReplicatedStorage:WaitForChild('Remotes'):WaitForChild('LeaveLobby')

--			GAME INFO			--
local PlaceId = 9479160887
local maxPlayers = 16

--		PLAYERS AND NODES		--
local Folder = script.Parent:WaitForChild('Players')
local node = script.Parent:WaitForChild('TeleportNode')
local node2 = script.Parent:WaitForChild('TeleportNode2')

--			UI STUFF			--

local playerCount = script.Parent:WaitForChild('billboard'):WaitForChild('SurfaceGui'):WaitForChild('TextLabel')
local timerText = script.Parent:WaitForChild('billboard'):WaitForChild('timer'):WaitForChild('TextLabel')
local intermissionLength = 30

local TimerActive = false

--			FUNCTIONS		--


function checkIfExists(Character) -- checks if player exists
	for _,value in pairs(Folder:GetChildren()) do
		if value.Value == Character then return true end
	end
	return false
end

function teleportParty()
	local Plrs = {}
	for _,value in pairs(Folder:GetChildren()) do 
		if not value then continue end
		table.insert(Plrs,Players:GetPlayerFromCharacter(value.Value))
	end
	local Code = ts:ReserveServer(PlaceId)
	ts:TeleportToPrivateServer(PlaceId,Code,Plrs)
	Folder:ClearAllChildren()	
end


function timer()
	if TimerActive then return end

	TimerActive = true
	intermissionLength = 30

	while task.wait() do
		for i = intermissionLength,0,-1 do
			timerText.Visible = true
			wait(1)
			intermissionLength =  i
			timerText.Text = i
			if #Folder:GetChildren() == 0   then
				intermissionLength = 30
				TimerActive = false
				return
			end
		end
		if #Folder:GetChildren() >= maxPlayers or intermissionLength == 0 then
			TimerActive = false
			teleportParty()				
		end
	end
end

function UpdateGui()
	playerCount.Text = tostring(#Folder:GetChildren())..'/'..tostring(maxPlayers)
end

script.Parent.Touched:Connect(function(part)
	if not part.Parent:FindFirstChild('Humanoid') then return end
	
	local player = part.Parent
	if not checkIfExists(player) then
		local Tag = Instance.new('ObjectValue')
		Tag.Value = player
		Tag.Parent = Folder
	end
	if #Folder:GetChildren() > 0 then
		timer()
	end
	
end)

script.Parent.TouchEnded:Connect(function(part)
	if not part.Parent:FindFirstChild('Humanoid') then return end

	for i,v in pairs(Folder:GetChildren()) do
		if v.Value == part.Parent then
			v:Destroy()
		end
	
	end

end)

Folder.ChildAdded:Connect(UpdateGui)
Folder.ChildRemoved:Connect(UpdateGui)

any error saying something about infinite yield?

Create a Region using Region3

Then use FindPartsInRegion3 to get all the parts that are in the region as a table loop through each part and check if the part includes humanoid if yes then check for player by using Players:GetPlayerFromCharacter(part.Parent) where your part is the part that is in the region.

no there are no errors but I think the problem is in the function Touched

I don’t think that’s the problem because it already checks here

script.Parent.Touched:Connect(function(part)
	if not part.Parent:FindFirstChild('Humanoid') then return end
	
	local player = part.Parent
	if not checkIfExists(player) then
		local Tag = Instance.new('ObjectValue')
		Tag.Value = player
		Tag.Parent = Folder
	end

The problem is with your .Touched you can’t do zoning stuff using touched event, thats where Region3 comes on.

you can just do :

function checkIfExists(Character) -- checks if player exists
    if Folder:FindFirstChild(Character) then
        return true
    else
        return false
    end
end

I think I will stop using TouchEnded and calculate the distance between the player and the teleporter

why do you use an instance instead of a table?

local Folder = script.Parent:WaitForChild('Players')

so I can detect when a child is added

I removed the “Folder” instance and created a table which detects when a value is inserted or deleted

Signal.__index = Signal
Signal.ClassName = "Signal"

function Signal.new()
	local self = setmetatable({}, Signal)
	self._bindableEvent = Instance.new("BindableEvent")
	self._argData = nil
	self._argCount = nil
	return self
end
function Signal:Fire(...)
	self._argData = { ... }
	self._argCount = select("#", ...)
	self._bindableEvent:Fire()
	self._argData = nil
	self._argCount = nil
end
function Signal:Connect(handler)
	if not (type(handler) == "function") then
		error(("connect(%s)"):format(typeof(handler)), 2)
	end
	return self._bindableEvent.Event:Connect(function()
		handler(unpack(self._argData, 1, self._argCount))
	end)
end
function Signal:Wait()
	self._bindableEvent.Event:Wait()
	assert(self._argData, "Missing arg data, likely due to :TweenSize/Position corrupting threadrefs.")
	return unpack(self._argData, 1, self._argCount)
end
function Signal:Destroy()
	if self._bindableEvent then
		self._bindableEvent:Destroy()
		self._bindableEvent = nil
	end
	self._argData = nil
	self._argCount = nil
end

local Folder = {
	Data = {},
}

Folder.ChildAdded = Signal.new()
Folder.ChildRemoved = Signal.new()

function insert(t: table, value: any, pos: number)
	if typeof(t) ~= "table" or value == nil then
		return
	end
	if pos then
		table.insert(t, pos, value)
	else
		table.insert(t, value)
	end
	Folder.ChildAdded:Fire(value)
end
function remove(t: table, value: any)
	if typeof(t) ~= "table" or value == nil then
		return
	end
	if table.find(t, value) then
		table.remove(t, table.find(t, value))
	end
	Folder.ChildRemoved:Fire(value)
end

--			SERVICES			--

local Players = game:GetService("Players")
local ts = game:GetService("TeleportService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

--			 REMOTES			--

local remote1 = ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("JoinLobby")
local remote2 = ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("LeaveLobby")

--			GAME INFO			--
local PlaceId = 9479160887
local maxPlayers = 16

--		PLAYERS AND NODES		--
-- local Folder = script.Parent:WaitForChild("Players")
local node = script.Parent:WaitForChild("TeleportNode")
local node2 = script.Parent:WaitForChild("TeleportNode2")

--			UI STUFF			--

local playerCount = script.Parent:WaitForChild("billboard"):WaitForChild("SurfaceGui"):WaitForChild("TextLabel")
local timerText = script.Parent:WaitForChild("billboard"):WaitForChild("timer"):WaitForChild("TextLabel")
local intermissionLength = 30

local TimerActive = false

--			FUNCTIONS		--

function checkIfExists(value) -- checks if player exists
    if Folder.Data[value] then return true end
	return false
end

function teleportParty()
	local Plrs = {}
	for _, value in pairs(Folder.Data) do
		if not value then
			continue
		end
		table.insert(Plrs, Players:GetPlayerFromCharacter(value))
	end
	local Code = ts:ReserveServer(PlaceId)
	ts:TeleportToPrivateServer(PlaceId, Code, Plrs)
	Folder:ClearAllChildren()
end

function timer()
	if TimerActive then
		return
	end

	TimerActive = true
	intermissionLength = 30

	while task.wait() do
		for i = intermissionLength, 0, -1 do
			timerText.Visible = true
			wait(1)
			intermissionLength = i
			timerText.Text = i
			if #Folder.Data == 0 then
				intermissionLength = 30
				TimerActive = false
				return
			end
		end
		if #Folder.Data >= maxPlayers or intermissionLength == 0 then
			TimerActive = false
			teleportParty()
		end
	end
end

function UpdateGui()
	playerCount.Text = tostring(#Folder.Data) .. "/" .. tostring(maxPlayers)
end

script.Parent.Touched:Connect(function(part)
	if not part.Parent:FindFirstChild("Humanoid") then
		return
	end

	local player = part.Parent
	if not checkIfExists(player) then
        insert(Folder.Data, player)
	end
	if #Folder.Data > 0 then
		timer()
	end
end)

script.Parent.TouchEnded:Connect(function(part)
	if not part.Parent:FindFirstChild("Humanoid") then
		return
	end

    remove(Folder.Data, part.Parent)
end)

Folder.ChildAdded:Connect(UpdateGui)
Folder.ChildRemoved:Connect(UpdateGui)

thank u but I fixed the problem your method is interesting thank you though

I found a way to make a better touchEnd credits to the channel DevGabe

--			SERVICES			--

local Players = game:GetService('Players')
local ts = game:GetService('TeleportService')
local ReplicatedStorage = game:GetService('ReplicatedStorage')

--			GAME INFO			--
local PlaceId = 9479160887
local maxPlayers = 16
local teleport = script.Parent

--		PLAYERS AND NODES		--
local Folder = script.Parent:WaitForChild('Players')
--			UI STUFF			--

local playerCount = script.Parent:WaitForChild('billboard'):WaitForChild('SurfaceGui'):WaitForChild('TextLabel')
local timerText = script.Parent:WaitForChild('billboard'):WaitForChild('timer'):WaitForChild('TextLabel')
local intermissionLength = 30

local TimerActive = false
local debounce = false
local DetectEnd = {}
local studs = 10

--			FUNCTIONS		--

function checkIfExists(Character) -- checks if player exists
	for _,value in pairs(Folder:GetChildren()) do
		if value.Value == Character then return true end
	end
	return false
end

function teleportParty()
	local Plrs = {}
	for _,value in pairs(Folder:GetChildren()) do 
		if not value then continue end
		table.insert(Plrs,Players:GetPlayerFromCharacter(value.Value))
	end
	local Code = ts:ReserveServer(PlaceId)
	ts:TeleportToPrivateServer(PlaceId,Code,Plrs)
	Folder:ClearAllChildren()	
end


function timer()
	if TimerActive then return end

	TimerActive = true
	intermissionLength = 30

	while task.wait() do
		for i = intermissionLength,0,-1 do
			timerText.Visible = true
			wait(1)
			intermissionLength =  i
			timerText.Text = i
			if #Folder:GetChildren() == 0   then
				intermissionLength = 30
				TimerActive = false
				return
			end
		end
		if #Folder:GetChildren() >= maxPlayers or intermissionLength == 0 then
			TimerActive = false
			teleportParty()				
		end
	end
end


script.Parent.Touched:Connect(function(part)
	if not part.Parent:FindFirstChild('Humanoid') then return end
	if debounce then return end
	debounce = true

	local player = part.Parent
	if not checkIfExists(player) then
		local Tag = Instance.new('ObjectValue')
		Tag.Value = player
		Tag.Parent = Folder
		table.insert(DetectEnd, player.HumanoidRootPart)
	end
	if #Folder:GetChildren() > 0 then
		timer()
	end
	debounce = false

end)

while wait() do
	table.foreach(DetectEnd, function(index, HumanoidRootPart)
		local checkDistance = (HumanoidRootPart.Position - teleport.Position).Magnitude
		if checkDistance > studs then
			local Player = game.Players:GetPlayerFromCharacter(HumanoidRootPart.Parent)
			for _,value in pairs(Folder:GetChildren()) do
				if value.Value == Player.Character then
					value:Destroy()
					
				end
			end
			
		end
	end)
	end