I made this script where if a player touches a part, it waits for “x” amount of seconds before teleporting it to another part. Basically like an elevator.
How do I rewrite the script as to so it teleports all the players that touched the part to a different location at the same time. Currently the script I wrote will only teleport each player individually, I did thought of placing all the player’s name that touched the part into a table, but I am unsure on how to actually write out said concept/idea.
local TP1 = game.Workspace.Spawns.Spawn1
local MainFloor = game.Workspace["Main Floor"]
local rand = Random.new()
local debounce = false
local TP1table = {}
TP1.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") and debounce == false then
debounce = true
task.wait(5)
local HumanoidRootPart = hit.Parent:FindFirstChild("HumanoidRootPart")
HumanoidRootPart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10, 10))
debounce = false
end
end)
What I am trying to achieve is when a player/ players touches the part, it will have a timer before it teleports everyone to a different part. Think of it like an elevator but instead of it teleporting only a specific player, I want it to teleport everyone that is on the part.
One flaw I noticed in my script was that the timer only starts whenever that specific player touches it, thus resulting in the teleportation to be individual based.
local TP1 = game.Workspace.Spawns.Spawn1
local MainFloor = game.Workspace["Main Floor"]
local rand = Random.new()
local debounce = false
local TP1table = {}
TP1.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") and debounce == false then
debounce = true
task.wait(.1)
if not table.find(TP1table,hit) then
table.insert(TP1table,hit)
end
debounce = false
end
end)
Put in a function here to detect when the player stops touching?
while true do
if #TP1table > 0 then
task.wait(5)
for I,v in pairs(TP1table) do
local HumanoidRootPart = v.Parent:FindFirstChild("HumanoidRootPart")
HumanoidRootPart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10, 10))
end
table.clear(TP1table) -- maybe wrong I can't remember if that exists
end
task.wait(0.1)
end
After the timer you can use game.Workspace:GetPartsInPart() to go through every player that is touching the part, instead of using a table to store players. This is a rough example of this:
TP1.Touched:Connect(function(hit)
local touchedPlayer = game.Players:GetPlayerFromCharacter(hit.Parent) -- improved version to check for player
if touchedPlayer and debounce == false then
debounce = true
task.wait(5)
for i, touchingPart in game.Workspace:GetPartsInPart(TP1) do -- equivalent of GetTouchingParts but detects non-collidible parts as well
local player = game.Players:GetPlayerFromCharacter(touchingPart.Parent)
if player then
local HumanoidRootPart = player.Character.HumanoidRootPart
HumanoidRootPart.CFrame = MainFloor.CFrame + Vector3.new(rand:NextInteger(-10, 10), 2 , rand:NextInteger(-10, 10))
end
end
debounce = false
end
end)
make table of players, then after X seconds make loop and teleport each player to base part, be sure you set collision group, or else those players can glitch because they will be one in each another at the same time, make something like this:
local playersToTeleport = {}
for i, v in game.Players:GetChildren() do
playersToTeleport[v] = 1 -- we only wan't key, soo we can set it to 1, it's a better practice to index than insert
end
task.wait(5)
for i,v in playersToTeleport do
-- teleport players to part, v is each player or object you saved to this table
end
It returns an array containing every single BasePart that has its hitbox shared with the given part (or a simpler term, touching). There is documentation about it as I’m not the best at explaining things
It is definitely more efficient than using a table to store players since it doesn’t require Touched to detect and add players throughout the cooldown time