Teleporting players standing on one part to the same server

What I am trying to do is get every player who stands on a part to teleport to the same server. Unfortunately, the Roblox Developer Hub page for the TeleportPartyAsync function only explains how to teleport all the players in the server, not just the people standing on the part. I heard that an array with players was one solution in this post, but I couldn’t figure out how to get the players in the array by having someone stand on a part…does anyone have any solutions for this?

In the end, I want my part to function similarly to Survivor’s pad that teleports the players to the place where actual content of the game is.

2 Likes

Step-by-Step


Simple explanation, too tired at the moment.

  • Run down the countdown.
  • Get players standing in the area. GetPlayerFromCharacter?
  • Run TeleportPartyAsync once the table of players is obtained(sufficient count).

Options:

  • Touched
  • Region3 ← possibly this
1 Like

I’ve made something like this in the past, you can use GetTouchingParts and get all the players inside an invisible box.

local Players = game:GetService"Players"
local function getplayersinbox(part)
    local players = {}
    local touching = part:GetTouchingParts()
    for i=1,#touching do
        local player = Players:GetPlayerFromCharacter(touching[i].Parent)
        if player then
            local found = false
            for k=1,#players do
                if players[k] == player then
                    found = true
                    break
                end
            end
            if not found then
                table.insert(players,player)
            end
        end
    end
    return players
end

If the part has CanCollide set to false, there has to be a function connected to .Touched for this to work.

Using TeleportPartyAsync shouldn’t be too hard.

local TeleportService = game:GetService"TeleportService"
local plrs = getplayersinbox(workspace.InvisibleTeleportBox)
TeleportService:TeleportPartyAsync(place_id,plrs)
--run this whenever it should teleport them
3 Likes

Basically, you could check player’s positions to see if they are in a box / region. I like to represent regions with parts, so this example used a part to represent a region. It’s easy to scale around too.

local matchPart = workspace:WaitForChild("matchPart") --Part to use to check

local function posInPos(pos,low,high)
	--A really long condition making sure that pos is between low and high
	return pos.X >= low.X and pos.X<=high.X and pos.Y >= low.Y and pos.Y<=high.Y and pos.Z >= low.Z and pos.Z<=high.Z
end

local function getPlayersInPart(part)
	local results = {}
	for _,plr in pairs(game:GetService("Players"):GetPlayers()) do
		--For every player, get their character
		local char = plr.Character
		if char then
			local humRoot = char:FindFirstChild("HumanoidRootPart")
			if humRoot then
				--Check to see if that character's humanoidRootPart is inside of the part
				local pos = humRoot.Position
				local low = part.Position - (part.Size/2)
				local high = part.Position + (part.Size/2)
				if posInPos(pos, low, high) then
					--If so, add it to the results
					table.insert(results, plr)
				end
			end
		end
	end
	--Return the results
	return results
end

--Now, to teleport when we have enough players (you could also add a timer)
local teleportAt = 1 --Players to teleport at
local placeIdToReserve = 0000000 --Place to reserve

local teleS = game:GetService("TeleportService")

while true do
	local results = getPlayersInPart(matchPart)
	--If enough players, teleport them to a new reserved server
	if #results > teleportAt then
		local code = teleS:ReserveServer(placeIdToReserve)
		teleS:TeleportToPrivateServer(placeIdToReserve,code,results)
	end
	wait(1)
end

Download the Demo:

The link below will let you download a working demo using the code above
regionCheckingTeleport.rbxl (15.8 KB)

4 Likes

The only problem with this is if players jump while waiting, then the won’t get teleported. .Touched has no way to check if a player steps off a part, so that won’t work very well (.TouchEnded is very buggy).

Simple fix: Create an invisible box and use GetTouchingParts on it instead of the platform they stand on.

:GetTouchingParts() does not work with non-cancollide parts. This would not work unless you added .Touched, at which point it would be easier to use Region3 or check positions.

If the part itself has CanCollide set to false, then this function will return an empty table UNLESS it has a TouchInterest

.Touched is still helpful because you will know whenever a player touches the part, so when a player touches the part you can check for every second for x seconds if there is still the required amount of players, and after that then you can teleport them. (add a debounce of course)
This way you’re not checking if the players are in the box if you know none are in the box.

You wouldn’t be able to use Region3 if the box was rotated, as far as i’m aware Region3s don’t have any way to rotate them.

You can still check in a rotated region if you wanted. the point is, with .Touched you would have to rely on another method to check if the player left that area, at which point it would be better to rely on that other method solely.

Will this script work?

local Players = game:GetService(“Players”)

local function getplayersinbox(InvisibleTeleportBox)
local players = {}

local touching = InvisibleTeleportBox:GetTouchingParts()

for i=1,#touching do
    local player = Players:GetPlayerFromCharacter(touching[i].Parent)
    
	if player then
        local found = false
        
		for k = 1, #players do
            if players[k] == player then
                found = true
                
				break
            end
        end
		
		if not found then
            table.insert(players, player)
        end
    end
end
return players

end

script.Parent.Touched:Connect(function()
getplayersinbox()
local TeleportService = game:GetService(“TeleportService”)
local plrs = getplayersinbox(workspace.InvisibleTeleportBox)
TeleportService:TeleportPartyAsync(2573878068, plrs)
end)

That should work, but I don’t see why you’re getting all players in the box every time its touched.

Something more like what i did in my game

local Players = game:GetService"Players"
local TeleportService = game:GetService"TeleportService"
local debounce = false
local function getplayersinbox(part)
    local players = {}
    local touching = part:GetTouchingParts()
    for i=1,#touching do
        local player = Players:GetPlayerFromCharacter(touching[i].Parent)
        if player then
            local found = false
            for k=1,#players do
                if players[k] == player then
                    found = true
                    break
                end
            end
            if not found then
                table.insert(players,player)
            end
        end
    end
    return players
end
workspace.InvisibleTeleportBox.Touched:Connect(function(hit)
    if not debounce and Players:GetPlayerFromCharacter(hit.Parent) then
		debounce = true
		for i=1,10 do 
			local players = getplayersinbox(workspace.InvisibleTeleportBox)
			if #players == 0 then
				debounce = false
				return
			end
			wait(1)
		end
		local players = getplayersinbox(workspace.InvisibleTeleportBox)
		if #players == 0 then
            debounce = false
			return
		end
        TeleportService:TeleportPartyAsync(2573878068,players)
        debounce = false
	end
end)
2 Likes