Glitchy Pressure Plate?

I’m trying to make a smooth pressure plate door for games like 2 Player Puzzle Obbies. It works, but the effects play repeatedly despite me even putting an effect debounce.

local Button = script.Parent.Button
local Hitbox = script.Parent.Hitbox
local Part = script.Parent.Parent.Part

Solidize = script.Parent.Configuration.Solidize.Value

SomeonesOn = false

EffectDB = false

local Green = BrickColor.new("Shamrock")
local Black = BrickColor.new("Black")

local Particles = Button.Particles
local Sound = Button.Sound


if Solidize == true then 
	Part.Transparency = .5
	Part.CanCollide = false
else
	Part.Transparency = 0
	Part.CanCollide = true
end

local function GetTouchingParts()
	local connection = Hitbox.Touched:Connect(function() end)
	local results = Hitbox:GetTouchingParts()
	connection:Disconnect()
	return results
end

while true do
	
	task.wait()
	
	local touchingParts = GetTouchingParts()

	for i, v in pairs(touchingParts) do
		if v.Parent:FindFirstChild("Humanoid") then
			
			if not EffectDB then
				EffectDB = true
				Particles:Emit(10)
				Sound:Play()
			end
			
			Button.BrickColor = Black

			if Solidize then
				Part.Transparency = 0
				Part.CanCollide = true
			else
				Part.Transparency = .5
				Part.CanCollide = false
			end
			
		else
			
			if EffectDB then
				EffectDB = false
			end
			
			Button.BrickColor = Green

			if Solidize then
				Part.Transparency = .5
				Part.CanCollide = false
			else
				Part.Transparency = 0
				Part.CanCollide = true
			end
			
		end
	end
end

image

Why is this happening?

Aight so, basically this whole snippet here is screwed up.

for i, v in pairs(touchingParts) do
		if v.Parent:FindFirstChild("Humanoid") then
			
			if not EffectDB then
				EffectDB = true
				Particles:Emit(10)
				Sound:Play()
			end
			
			Button.BrickColor = Black

			if Solidize then
				Part.Transparency = 0
				Part.CanCollide = true
			else
				Part.Transparency = .5
				Part.CanCollide = false
			end
			
		else
			
			if EffectDB then
				EffectDB = false
			end
			
			Button.BrickColor = Green

			if Solidize then
				Part.Transparency = .5
				Part.CanCollide = false
			else
				Part.Transparency = 0
				Part.CanCollide = true
			end
			
		end
	end

When you use GetTouchingParts, you have to be aware that a player instance has many many many parts, which dont all have Humanoid as a child, and several of which that do. That means you’re effectively setting and resetting your EffectDB multiple times for every single player on the part with each iteration of the loop. Thus particles and sounds will be spammed.

What you want to do instead is something like this. Have two variables, one to act as a flag to see if there was a human standing on the part this iteration(You already have a variable that could be used for this called someonesOn), and another to check whether to emit effects(your effectdb). You want to set someonesOn to false before the for loop, and set it to true inside the for loop if a humanoid is found. At the end of the script, after the foor loop, you can then reset effectDB if someonesOn is false.

1 Like

For a debounce to work with Touched events and a Humanoid it needs a task.wait(some time that alows the touched event to fire, but not fire again each and every time a player’s part touches the Hitbox.
The while true do task.wait() will allow your GetTouchingParts function to fire every .03 seconds.
Put a print("player touched") statement right after your Touched event. That will show you exactly how many times the player (or their touching Parts) are touching the Hitbox.

1 Like

This makes a lot more sense, but I still don’t fully understand. I switched my script a little bit but it’s still spamming the particles because of how accessories’ handles aren’t direct children of the character model. Could you walk me through it a little bit more? Sorry for needing this much help.

local Button = script.Parent.Button
local Hitbox = script.Parent.Hitbox
local Part = script.Parent.Parent.Part

Solidize = script.Parent.Configuration.Solidize.Value

SomeonesOn = false

EffectDB = false

local Green = BrickColor.new("Shamrock")
local Black = BrickColor.new("Black")

local Particles = Button.Particles
local Sound = Button.Sound


if Solidize == true then 
	Part.Transparency = .5
	Part.CanCollide = false
else
	Part.Transparency = 0
	Part.CanCollide = true
end

local function GetTouchingParts()
	local connection = Hitbox.Touched:Connect(function() end)
	local results = Hitbox:GetTouchingParts()
	connection:Disconnect()
	return results
end

while true do
	
	task.wait()
	
	local touchingParts = GetTouchingParts()
	
	for i, v in pairs(touchingParts) do
		if v.Parent:FindFirstChild("Humanoid") then
			
			SomeonesOn = true
			
			Button.BrickColor = Black

			if Solidize then
				Part.Transparency = 0
				Part.CanCollide = true
			else
				Part.Transparency = .5
				Part.CanCollide = false
			end
			
		else
			
			Button.BrickColor = Green

			if Solidize then
				Part.Transparency = .5
				Part.CanCollide = false
			else
				Part.Transparency = 0
				Part.CanCollide = true
			end
			
		end
	end
	if SomeonesOn then
		EffectDB = true
		Particles:Emit(10)
		Sound:Play()
	else
		EffectDB = false
	end
end
1 Like

Ehh, the way you do it there, the EffectDB value ends up serving no purpose. You want a value that resets in the start of the while loop, or anytime before the for loop, someonesOn is never reset. And then you want a variable you can use to tell whether the effect has been played yet or not. This value should only reset when theres nobody on the part.

Essentially something like this

local hasEffectEmitted = false
local isHumanoidOn = false

while true do
	isHumanoidOn = false
	
	local touchingParts = GetTouchingParts()
	for i, v in pairs(touchingParts) do
		if v.Parent:FindFirstChild("Humanoid") then
			isHumanoidOn = true
			break
		end
	end
	
	if not hasEffectEmitted and isHumanoidOn then
		hasEffectEmitted = true
		Particles:Emit(100)
		Button.BrickColor = BrickColor.random()
	elseif not isHumanoidOn then
		hasEffectEmitted = false
		Button.BrickColor = BrickColor.Black()
	end
	
	task.wait()
end
2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.