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