Touched event issue

I’m working on a pressure plate that would keep a door open while a player is stepping on it using tweening. The issue is that you can cheese it, and if you keep stepping back and forth the door will remain open even if you’ve stepped off the pressure plate.

local pressurePlate = script.Parent.Parent.PressurePlate
local door = script.Parent.Parent.Door
local goal1 = script.Parent.Parent.GoalPart1
local goal2 = script.Parent.Parent.GoalPart2

local tweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Linear)

local openDoor = {}
openDoor.CFrame = goal1.CFrame
local openDoorTween = tweenService:Create(door, tweenInfo, openDoor)

local closeDoor = {}
closeDoor.CFrame = goal2.CFrame
local closeDoorTween = tweenService:Create(door, tweenInfo, closeDoor)

local touching = {}

pressurePlate.Touched:Connect(function(touch)
	if touch.Name == "HumanoidRootPart" and #touching < 1 then
		table.insert(touching, touch)
		openDoorTween:Play()
	end
end)

pressurePlate.TouchEnded:Connect(function(touch)
	if touch.Name == "HumanoidRootPart" then
		table.remove(touching, touching[touch])
	end
	
	if #touching < 1 then
		closeDoorTween:Play()
	end
end)

Is there any solution to prevent breaking it?

One way to prevent cheesing would be to keep track of the number of characters touching the pressure plate, rather than a list of the characters themselves.

local pressurePlate = script.Parent.Parent.PressurePlate
local door = script.Parent.Parent.Door
local goal1 = script.Parent.Parent.GoalPart1
local goal2 = script.Parent.Parent.GoalPart2

local tweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Linear)

local openDoor = {}
openDoor.CFrame = goal1.CFrame
local openDoorTween = tweenService:Create(door, tweenInfo, openDoor)

local closeDoor = {}
closeDoor.CFrame = goal2.CFrame
local closeDoorTween = tweenService:Create(door, tweenInfo, closeDoor)

local touching = 0

pressurePlate.Touched:Connect(function(touch)
	if touch.Name == "HumanoidRootPart" and touching == 0 then
		touching = 1
		openDoorTween:Play()
	end
end)

pressurePlate.TouchEnded:Connect(function(touch)
	if touch.Name == "HumanoidRootPart" then
		touching = 0
	end
	
	if touching == 0 then
		closeDoorTween:Play()
	end
end)
1 Like

Tried it. Still manages to break.

Okay. What’s happening specifically?

If I keep stepping on it back and forth, it eventually breaks and the door still remains open after stepping off. I assume the Touched event might be slightly delayed (input lag), but I’m not sure

table.remove(touching, touching[touch])

table.remove takes a table and an index, touching[touch] probably always returns nil. you want to find the touch and remove it like so

pressurePlate.TouchEnded:Connect(function(touch)
	if touch.Name == "HumanoidRootPart" then
		local index = table.find(touching, touch)
		if index then
			table.remove(touching, index)
		end
	end

I think you meant to use touching += 1 for adding a player and touching -= 1 when touch ended.

Your current code will only keep track of one player.

Still the same issue. Eventually it breaks

pressurePlate.TouchEnded:Connect(function(touch)
	if touch.Name == "HumanoidRootPart" then
		local index = table.find(touching, touch)
		if index then
			table.remove(touching, index)
			closeDoorTween:Play()
		end
	end
end)

This is basically what happens

Try delaying the door opening moment. so that when a player steps the will have to wait for the door open.