How to detect if a part have more than one player touching it?

I am recently suffering from a problem where I cannot find a way to detect when at least two players are touching a part, and then teleport them together to another part of the map. Is there a correct way to do this without any problems?

you’d index them to a table and check the others touched state.

You could use :GetTouchingParts() and derive the players from it.

1 Like

You could possibly look into Region3 although I’m not that familiar with it myself, it could work.

Best way to do this would be to keep an array of Players and check for Touched() and TouchEnded()

local PlayerService = game:GetService("Players")
local Players = {}
local Part = script.Parent

function CheckHumanoid(hit)
     local Humanoid = hit.Parent:FindFirstChild("Humanoid")
     if Humanoid and Humanoid.ClassName == "Humanoid" then
          return PlayerService:GetPlayerFromCharacter(hit.Parent)
     end
end

Part.Touched:Connect(function(hit)
     local Player = CheckHumanoid(hit)
     if Player then
          Players[Player.UserId] = Player
     end
end)

Part.TouchEnded:Connect(function(hit)
     local Player = CheckHumanoid(hit)
     if Player then
          Players[Player.UserId] = nil
     end
end)
2 Likes

I don’t see the need of Region3 on this one, since i don’t want to make a whole local a teleporter, only one part when the player touch it.

1 Like

Here could be a more advanced version if you want to apply this logic to multiple parts:

local Players = game:GetService("Players")
local TouchedDictionary = {}

Players.PlayerAdded:Connect(function(player)
   TouchedDictionary[player] = {}
end)

local function AddPartToTouched(part, player)
   if table.find(TouchedDictionary[player], part) then
      return
   end
   table.insert(TouchedDictionary[player], part)
end 

local function RemovePartFromTouched(part, player)
    local ind = table.find(TouchedDictionary[player], part)
    if ind then
      table.remove(TouchedDictionary[player], ind)
    end
end

local function IsTouching(part, player)
    return table.find(TouchedDictionary[player], part)
end


-- Sample code
part.Touched:Connect(function(hit)
    local player = Players:GetPlayerFromCharacter(hit.Parent)
    if player then
        AddPartToTouched(part, player)
    end
end)

part.TouchEnded:Connect(function(hit)
    local player = Players:GetPlayerFromCharacter(hit.Parent)
    if player then
       RemovePartFromTouched(part, player)
    end
end)

-- Sample code
local randomPart = ur.part
event.OnServerEvent:Connect(function(player)
   if IsTouching(randomPart, player) then
         -- the player is touching this part!
   end
end)

You could also use a dictionary instead of an array if that’s your preference.

I don’t see a reason to make something so complicated for this. This is just for basic detection if multiple people are touching a part.

Edit:
There is also a typo on your script, line 5.

This seems to work, but it will teleport only the player what is touching it at the moment right? Because I have some sounds effects what only occurs when the teleport works, teleporting another player after will make the same sound again making it useless.

It’s not necessarily a complication, it’s actually more of a simplification :wink:

Suppose OP wanted to detect more than one part, this would probably be more convenient on their end.

Btw can you point out the typo, I can’t find it D:

EDIT: Thank you @M9_Sigma @GreatPanda3 for the fix

Inside of the PlayerAdded listener