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.
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)
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.
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
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