Hello, I'm making a puzzle where if two people stand on a button together, a part dissapears. If one of them leaves, it will reappear.
This is what I have:
local TweenService = game:GetService("TweenService") local didOnce = true local box = script.Parent local names = {} box.Touched:Connect(function(object) if (object.Name == "Torso" or object.Name == "Left Leg" or object.Name == "Right Leg" or object.Name == "Head" or object.Name == "LeftArm" or object.Name == "Right Arm" or object.Name == "HumanoidRootPart") then if #names == 0 then print("hi.") table.insert(names,object.Parent.Name) else for x, c in pairs(names) do if object.Parent.Name == c then break elseif x == #names then table.insert(names,object.Parent.Name) print(object.Parent.Name) print(#names) if #names == 2 then if didOnce then workspace.Puzzle.DesertArchTwoButton2.SandstoneWall1.CanCollide = false workspace.Puzzle.DesertArchTwoButton2.SandstoneWall1.Transparency = 1 didOnce = false end end end end end end end) box.TouchEnded:Connect(function(object) if (object.Name == "Torso" or object.Name == "Left Leg" or object.Name == "Right Leg" or object.Name == "Head" or object.Name == "LeftArm" or object.Name == "Right Arm" or object.Name == "HumanoidRootPart") then if #names == 0 then print("hi.") table.insert(names,object.Parent.Name) else for x, c in pairs(names) do if object.Parent.Name == c then break elseif x == #names then table.insert(names,object.Parent.Name) end end end if(#names < 2) then workspace.Puzzle.DesertArchTwoButton2.SandstoneWall1.CanCollide = true workspace.Puzzle.DesertArchTwoButton2.SandstoneWall1.Transparency = 0 end end end)
However, this does not function when someone leaves the button. Does anyone have a solution?
I don't see what's wrong with this except for the fact that it uses dependant touch listeners. What if the player leaves? It wouldn't fire touch ended correctly at least, the character wouldn't exist even if it did! Even if it does, I would suggest constant checking, it's safer and guarantees the amount of player characters on the brick. To do this, use renderstepped, or while true loop with a wait since it's more memory efficient, and use :Gettouxhingparts(), like this:
while true do wait(.1) local touchingCharacters = {} local connection = part.Touched:Connect(function()end) -- this isn't nessesary but this is a for safety, a neat trick someone told me, usually, when two bricks of the same anchored value touch, for example both anchored or both unanchored, this won't be found when using grttouxhingparts, but it does work when you connect a touch function with one of the bricks, then you can disconnect it later. for i,v in pairs(part:GetTouchingParts()) do -- goes through touching parts if v.Parent:FindFirstChildWhichIsA"Humanoid" then -- to check if it'd a character, and the whichisa is for safety also, it's just incase the humanoid is named something different, it will still have the class name humanoid therefor this will detect it. local char = v.Parent -- sets character, I'm too lazy to wrote the code for if it's a player, just use get player from character and if it'd not nil, it's a real player. if table.find(touchingCharacters, char) == nil then -- for safety incase the character was already accounted for, because there are more than one part that touches things because there's two legs and stuff, you get it. table.insert(char) -- added so now other parts of the same character will not count, and also just to have the character in there since we need to find how many there are, so it serves 2 purposes to do this. end end end connection:Disconnect() -- said above, it's memory efficient to disconnect it afterwards because it's not needed anymore if #touchingCharacters >=2 then -- checks if there's two or more touching characters --do whatever, also you have the character instances so you can do stuff like this: touchingCharacters[1].Head:Destroy() end end
I hope this helps owo :3 yip