How do I teleport players from a table?

The first part of my script inserts the character of all players that touched the part into a table. I do not know how to get the table of players to be teleported AT THE SAME time to a different part.

local TP1 = game.Workspace.Spawns.Spawn1
local MainFloor = game.Workspace["Main Floor"]

local rand = Random.new()
local debounce = false
local lift1plrc = {}

TP1.Touched:Connect(function(hit)
	
	if hit.Parent:FindFirstChild("Humanoid") and debounce == false then
		table.insert(lift1plrc, hit.Parent)
		debounce = true
		print(lift1plrc)
	end
end)

---------------------------------------- I think the problem is below --------------------------------------------

for i, v in pairs(lift1plrc) do
	local HumanoidRootPart = table.find(lift1plrc, _.Parent:FindFirstChild("HumanoidRootPart"))
	HumanoidRootPart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10, 10))
	debounce = false
end
4 Likes

I assume your problem is players are not teleporting at the same time? or that players do not teleport?
Although I don’t see an issue with your code, here is an improved version:

-- Define a function to teleport all players
local function teleportAllPlayers()
    for i, player in pairs(lift1plrc) do
        local HumanoidRootPart = player:FindFirstChild("HumanoidRootPart")
        if HumanoidRootPart then
            HumanoidRootPart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10, 10))
        end
    end
    -- Reset the debounce and the player list
    debounce = false
    lift1plrc = {}
end

-- Call the function when you want to teleport all players
teleportAllPlayers()

We use a function instead so you can choose when you want to teleport these players, for example, every 30 seconds.

1 Like

Just tested it the teleport function does not work.

local TP1 = game.Workspace.Spawns.Spawn1
local MainFloor = game.Workspace["Main Floor"]

local rand = Random.new()
local debounce = false
local lift1plrc = {}

TP1.Touched:Connect(function(hit)
	
	if hit.Parent:FindFirstChild("Humanoid") and debounce == false then
		table.insert(lift1plrc, hit.Parent)
		debounce = true
		print(lift1plrc)
	end
end)

local function TP1lift()
	for i, player in pairs(lift1plrc) do
		print(lift1plrc)
		local HumanoidRootPart = player:FindFirstChild("HumanoidRootPart")
		if HumanoidRootPart then
			HumanoidRootPart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10, 10))
		end
	end
	debounce = false
end

TP1lift()

Could you elaborate on why it doesn’t work? Does it output an error, are the players simply not teleporting? What exactly is the issue?

There is no error message, the players did not get teleported. I think the issue is here.

	for i, player in pairs(lift1plrc) do
		print(lift1plrc)
----------------------------------------------------------below---------------------------------------------------------
		local HumanoidRootPart = player:FindFirstChild("HumanoidRootPart")
		if HumanoidRootPart then
			HumanoidRootPart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10, 10))
		end
	end
	debounce = false
end

TP1lift()
1 Like

We are iterating through lift1plrc which is a table containing the characters and not the players, That means player in this case is the character itself, not the PlayerInstance

You’re calling TP1lift() at the end of your script, but at this point, the lift1plrc table is likely still empty because TP1.Touched event might not have been triggered yet. This means that the for loop inside TP1lift() won’t run any iterations. Make sure you only call TP1lift() when neccessary.

Also, what does the table print? is there a character inside of lift1plrc?

1 Like

The table print was just a test to make sure the player’s character are there.

I just fixed the script and the teleportation worked, but I am unsure where or how to add a timer to teleport all players at the same time. I tried placing a wait() script, but that only delayed the other scripts from executing their code. The entire script consists of 3 elevators that are suppose to run their timer/countdown simultaneously and teleport all the players if said timer runs up on that specific elevator.

Example:
Elevator 1 timer (30) seconds
Elevator 2 timer (20) seconds
Elevator 3 timer (10) seconds

results:
Elevator 3 will teleport all the players in that specific elevator’s table after the 10 seconds, followed by 2 and 3.

local TP1 = game.Workspace.Spawns.Spawn1    ---Elevator 1, where players will spawn in
local MainFloor = game.Workspace["Main Floor"] ---Destination where the elevator will arrive at

local rand = Random.new()
local debounce = false
local lift1plrc = {}  --Elevator table that consists the player's character that touched/spawned on the part

local function TP1lift()
	wait(5)
	for i, player in pairs(lift1plrc) do
		local HumanoidRootPart = player:FindFirstChild("HumanoidRootPart")
		if HumanoidRootPart then
			HumanoidRootPart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10, 10))
		end
	end
	debounce = false
end	
	

TP1.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") and debounce == false then
		table.insert(lift1plrc, hit.Parent)
		debounce = true
		TP1lift()
	end
end)	

This current script will teleport players INDIVIDUALLY after the wait() timer runs out. I am aware that using wait() creates the issue, but what other alternatives are there for a timer system or simple countdown that would not disrupt the timer/countdown of the other elevators?

It only fires once, that is why it doesnt work. Also why do you put the players in a table? Why dont u teleport the player once he touches the Basepart with
Character:PivotTo(Part.CFrame)

1 Like

The teleportation works, but only individually. My aim is to teleport everyone that touched the part after a set amount of time. Basically like waiting for an elevator to reach the floor, then everyone arrive at the same time.

Try this:

local waitBeforeTeleport = 4 -- Change this to match how long it takes to teleport

local workspace = game:GetService("Workspace")
local runService = game:GetService("RunService")

local TP1 = workspace.Spawns.Spawn1
local MainFloor = workspace["Main Floor"]

local lift1plrc = {}

local rand = Random.new()

local debounce
local connection
local timePassed = 0

TP1.Touched:Connect(function(hit)
	if debounce then return end

	if hit.Parent and hit.Parent:FindFirstChildWhichIsA("Humanoid") then
		debounce = true
		table.insert(lift1plrc, hit.Parent.PrimaryPart)
		print(lift1plrc)

		if not connection then connection = runService.PostSimulation:Connect(function(deltaTime)
				timePassed += deltaTime

				if timePassed >= waitBeforeTeleport then
					connection:Disconnect()
					connection = nil
					timePassed = 0

					for _, primaryPart in lift1plrc do
						if primaryPart then primaryPart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10, 10)) end
					end

					table.clear(lift1plrc)
				end
			end)
		end

		task.wait()
		debounce = false
	end
end)

You can adjust how long it takes for the players to teleport by changing the waitBeforeTeleport value

Important edit: @ahmingiscool I just made a small but important correction to the script, now the table will be cleaned-up after the players are teleported

1 Like

Thanks! The script worked, but there are a few things I do not understand. Can you explain?

What does the local connection variable you created mean or do?
How does RunService work in this script or what does it do?
I do not understand the logic of this line. What is PostSimulation:Connect(function(deltaTime)

				timePassed += deltaTime

				if timePassed >= waitBeforeTeleport then
					connection:Disconnect()
					connection = nil
					timePassed = 0```
2 Likes

RunService is a service that contains many useful loops, PostSimulation is the equivalent of the Heartbeat loop. When you create a connection by using :Connect(), you can optionally store the connection inside of a variable so you can disconnect it later on. I’m storing the connection returned by the runService.PostSimulation:Connect inside of a variable named connection so that I can stop the loop from running after the players are teleported, then reset the loop so that it works again for the next group of players else the code will only run correctly once

1 Like

Thank you for the explanation. I will apply this logic in the future.

1 Like

Hello there again, I tried personalizing the script for my other elevators but there seemed to be a problem where the timer no longer works and it instead teleports all players whenever the part is touched.

I tried separating each variable and timer into their own thing, but clearly there is something I still do not understand. It would be great if you can assist me.

TP2 and TP3 hit function are just copypasted and later substituted with their own variable and timer.

local TP1 = game.Workspace.Spawns.Spawn1
local TP2 = game.Workspace.Spawns.Spawn2
local TP3 = game.Workspace.Spawns.Spawn3
local MainFloor = game.Workspace["Main Floor"]

local TP1timer = 3
local TP2timer = 6
local TP3timer = 9

local timePassed1 = 0
local timePassed2 = 0
local timePassed3 = 0

local lift1plrc = {}    --LIFT 1 player character
local lift2plrc = {}   --LIFT 2 player character
local lift3plrc = {}   --LIFT 3 player character

local rand = Random.new()
local debounce1 = false
local debounce2 = false
local debounce3 = false
local runService = game:GetService("RunService")

local connection1
local connection2
local connection3



TP1.Touched:Connect(function(hit)
	if debounce1 then return end
	
	if hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
		debounce1 = true
		table.insert(lift1plrc, hit.Parent.PrimaryPart)
		
		if not connection1 then connection1 = runService.PostSimulation:Connect(function(deltaTime)
				timePassed1 += deltaTime
				
				if timePassed1 >= TP1timer then
					connection1:Disconnect()
					connection1 = nil
					timePassed1 = 0
				end
				
				for _, primarypart in lift1plrc do
					if primarypart then primarypart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10,10)) end
				end	
				
				table.clear(lift1plrc)
				
				
			end)
			
		end
		
		task.wait()
		debounce1 = false
	end 	
		
end)



TP2.Touched:Connect(function(hit)
	if debounce2 then return end

	if hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
		debounce2 = true
		table.insert(lift2plrc, hit.Parent.PrimaryPart)

		if not connection2 then connection2 = runService.PostSimulation:Connect(function(deltaTime)
				timePassed2 += deltaTime

				if timePassed2 >= TP2timer then
					connection2:Disconnect()
					connection2 = nil
					timePassed2 = 0
				end

				for _, primarypart in lift2plrc do
					if primarypart then primarypart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10,10)) end
				end	

				table.clear(lift2plrc)


			end)

		end

		task.wait()
		debounce2 = false
	end 	

end)



TP3.Touched:Connect(function(hit)
	if debounce3 then return end

	if hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
		debounce3 = true
		table.insert(lift3plrc, hit.Parent.PrimaryPart)

		if not connection3 then connection3 = runService.PostSimulation:Connect(function(deltaTime)
				timePassed3 += deltaTime

				if timePassed3 >= TP3timer then
					connection3:Disconnect()
					connection3 = nil
					timePassed3 = 0
				end

				for _, primarypart in lift3plrc do
					if primarypart then primarypart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10,10)) end
				end	

				table.clear(lift3plrc)


			end)

		end

		task.wait()
		debounce3 = false
	end 	

end)```

I’d recommend using a module to handle the logic. Luckily I had time today to create and test this module for you:

local runService = game:GetService("RunService")

local MainFloor = workspace["Main Floor"]

local rand = Random.new()

return function(touchPart: BasePart, waitBeforeTeleport: number)
	local rootParts = {}

	local debounce
	local connection
	local timePassed = 0

	touchPart.Touched:Connect(function(basePart)
		if debounce then return end

		if basePart.Parent and basePart.Parent:FindFirstChildWhichIsA("Humanoid") then
			debounce = true
			table.insert(rootParts, basePart.Parent.PrimaryPart)
			print(rootParts)

			if not connection then connection = runService.PostSimulation:Connect(function(deltaTime)
					timePassed += deltaTime

					if timePassed >= waitBeforeTeleport then
						connection:Disconnect()
						connection = nil
						timePassed = 0

						for _, part in rootParts do
							if part then part.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10, 10)) end
						end

						table.clear(rootParts)
					end
				end)
			end

			task.wait(1) -- I found 1 prevents the table from filling up unnecessarily, but change it back to task.wait() if you prefer
			debounce = false
		end
	end)
end

and this is how to use the module (To work correctly it needs to be used inside of a server script though):

local TPmodule = require(script.TPmodule) -- Change "script.TPmodule" to where you stored the module

local Spawns = game:GetService("Workspace").Spawns

TPmodule(Spawns.Spawn1, 3) -- The first argument is the TP part and the second is the wait before teleport
TPmodule(Spawns.Spawn2, 6)
TPmodule(Spawns.Spawn3, 9)
1 Like

Oh Yeah, a module script! I was so eager to use a module script on so many other things but it has not once crossed my mind on this scenario. Your time and help is much appreciated!

1 Like

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