Debounce an sfx for a proximityprompt

Hello, I would like to learn how to use debounce for an sfx when using a proximity prompt.

I found the page, Debounce Patterns with:

if sound and not sound.IsPlaying then
		 sound:Play()
	 end

but I tried and nothing works.

Currently everything works but when I touch the part it plays the sfx lots of times, the problem is that I don’t know where to add the 2 sfx (soundpass and sounderror) and I don’t know how to add a debounce without destroy the script.

2 Likes

You are not setting the debounce variable (canhit). It will always remain true.

You need to set it to false and then back to true once the function is done

local canhit = true

touchPart.Touched:Connect(function()
    if canhit == true then
         canhit = false
         -- Code goes in the middle
         canhit = true
    end
end)

Tell me if this new version is better? I added what you indicated to lines that seem almost correct to me

ah, currently the sfx only play 2 or 3 times and then nothing

Correct

I have a new problem rn :confused:

image

local touchpart = game.Workspace:WaitForChild("Game"):WaitForChild("System"):WaitForChild("DoorC"):WaitForChild("KeycardDoor"):WaitForChild("hitbox")
local Players = game.Players
local Player = Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local text = player.PlayerGui.Notif.Text
local canhit = true

touchpart.Touched:Connect(function(hit)
	if canhit == true then
		canhit = false
		local name = hit.Parent.Name
		if hit and hit.Parent:FindFirstChild("Humanoid") then
			local hasKeyCard = false
			-- Check if the player has the key card
			local Tool = player.Backpack:FindFirstChild("KEYCARD") or player.Character:FindFirstChild("KEYCARD")
			if Tool then
				soundpass:Play()
				hasKeyCard = true
			end

			if not hasKeyCard then
				sounderror:Play()
				text.Visible = true
				wait(3)
				text.Visible = false
			end
		end
	canhit = true
	end
end)

try using local Players = game:GetService("Players")

By the looks of it, this code is running on the server in a Script. The server does not have a "local player’ so calling game.Players.LocalPlayer on the server returns nil.

From the code you provided it looks like you are just playing a sound and updating gui text. That could be done safely on the client. So change the Script to a LocalScript and put it in StarterPlayerScripts.

Just remember that the client can change any value on it’s own machine (this means hackers can change hasKeyCard to true even if they don’t have a keycard).

If you are doing something that requires validation (like giving the player a tool all players can see) it must be done on the server.

I understand but I would like the door to only open for the player who has the pass card
and the other players who do not have the pass card see the door closed

so it’s on the client ?

Yes you should put that code on the client. The error you were getting was because you were running it in a Server Script.

Currently I have no error but nothing works, not even the door and the proximity

local door = script.Parent:WaitForChild("Door")
if not door.PrimaryPart then
	door.PrimaryPart = door:WaitForChild("HINGE")
end


--CONFIGURATION--
local keycardName = "KEYCARD"

local timeOpen = 8

local goalRot = 105

local openLength = 2
local closeLength = 1.2
-----------------

local pos = door:GetPivot().Position
local initialRot = door.PrimaryPart.Orientation.Y
local replicate = game.ReplicatedStorage
local sounderror = replicate.SFX.Error
local soundpass = replicate.SFX.Pass

local opened = false
local animationHappening = false

local prompt = Instance.new("ProximityPrompt")
prompt.ObjectText = "Keycard Door"
prompt.ActionText = "Open door"
prompt.KeyboardKeyCode = Enum.KeyCode.E
prompt.HoldDuration = 0
prompt.RequiresLineOfSight = false
prompt.MaxActivationDistance = 8
prompt.Parent = door

local touchpart = game.Workspace:WaitForChild("Game"):WaitForChild("System"):WaitForChild("DoorC"):WaitForChild("KeycardDoor"):WaitForChild("hitbox")
local Players = game.Players
local Player = game:GetService("Players")
local PlayerGui = Player:WaitForChild("PlayerGui")
local text = player.PlayerGui.Notif.Text
local canhit = true

touchpart.Touched:Connect(function(hit)
	if canhit == true then
		canhit = false
		local name = hit.Parent.Name
		if hit and hit.Parent:FindFirstChild("Humanoid") then
			local hasKeyCard = false
			-- Check if the player has the key card
			local Tool = player.Backpack:FindFirstChild("KEYCARD") or player.Character:FindFirstChild("KEYCARD")
			if Tool then
				soundpass:Play()
				hasKeyCard = true
			end

			if not hasKeyCard then
				sounderror:Play()
				text.Visible = true
				wait(3)
				text.Visible = false
			end
		end
		canhit = true
	end
end)

local cfv = Instance.new("CFrameValue")
cfv.Value = door:GetPivot()
cfv.Parent = door

cfv:GetPropertyChangedSignal("Value"):Connect(function()
	door:PivotTo(cfv.Value)
end)


function ease(x)
	local n1 = 7.5625
	local d1 = 2.75

	if (x < 1 / d1) then
		return n1 * x * x
	elseif (x < 2 / d1) then
		x -= 1.5/d1
		return n1 * (x) * x + 0.75
	elseif (x < 2.5 / d1) then
		x -= 2.25/d1
		return n1 * (x) * x + 0.9375
	else
		x -= 2.625/d1
		return n1 * (x) * x + 0.984375
	end
end


function closeDoor()

	if opened and not animationHappening then
		opened = false
		animationHappening = true

		local currentRot = door.PrimaryPart.Orientation.Y

		local closeStarted = tick()
		while true do
			local x = (tick() - closeStarted) / closeLength
			local rotOffset = ease(x) * -goalRot

			cfv.Value = CFrame.new(pos) * CFrame.Angles(0, math.rad((initialRot + goalRot) + rotOffset), 0)

			if x >= 1 then
				break
			end

			game:GetService("RunService").Heartbeat:Wait()
		end

		animationHappening = false
		prompt.Enabled = true
	end
end

function openDoor()

	if not opened and not animationHappening then
		opened = true
		animationHappening = true

		prompt.Enabled = false

		local openStarted = tick()

		while true do
			local x = (tick() - openStarted) / openLength
			local rotOffset = ease(x) * goalRot

			cfv.Value = CFrame.new(pos) * CFrame.Angles(0, math.rad(initialRot + rotOffset), 0)

			if x >= 1 then
				break
			end

			game:GetService("RunService").Heartbeat:Wait()
		end

		animationHappening = false
	end
end



prompt.Triggered:Connect(function(plr)

	local char = plr.Character
	if char and char:FindFirstChild("Humanoid") and char.Humanoid.Health > 0 then

		if char:FindFirstChild(keycardName) and char[keycardName]:IsA("Tool") then

			task.spawn(openDoor)
			task.wait(timeOpen)
			task.spawn(closeDoor)
		end
	end
end)

look at line 1

Yes it’s good normally
image
?

in second dev place with just the door system it works and when i put it in my game i get this error
image

local door = script.Parent:WaitForChild("Door")
if not door.PrimaryPart then
	door.PrimaryPart = door:WaitForChild("HINGE")
end


--CONFIGURATION--
local keycardName = "KEYCARD"

local timeOpen = 8

local goalRot = 105

local openLength = 2
local closeLength = 1.2
-----------------

local pos = door:GetPivot().Position
local initialRot = door.PrimaryPart.Orientation.Y
local replicate = game.ReplicatedStorage
local sounderror = replicate.sfx.Error
local soundpass = replicate.sfx.Pass

local opened = false
local animationHappening = false

local prompt = Instance.new("ProximityPrompt")
prompt.ObjectText = "Keycard Door"
prompt.ActionText = "Open door"
prompt.KeyboardKeyCode = Enum.KeyCode.E
prompt.HoldDuration = 0
prompt.RequiresLineOfSight = false
prompt.MaxActivationDistance = 8
prompt.Parent = door

local touchpart = game.Workspace:WaitForChild("Game"):WaitForChild("System"):WaitForChild("door"):WaitForChild("KeycardDoor"):WaitForChild("hitbox")
local player = game.Players.LocalPlayer
local text = player.PlayerGui.Notif.Text
local canhit = true

touchpart.Touched:Connect(function(hit)
	if canhit == true then
		canhit = false
		local name = hit.Parent.Name
		if hit and hit.Parent:FindFirstChild("Humanoid") then
			local hasKeyCard = false
			-- Check if the player has the key card
			local Tool = player.Backpack:FindFirstChild("KEYCARD") or player.Character:FindFirstChild("KEYCARD")
			if Tool then
				task.wait(1)
				soundpass:Play()
				hasKeyCard = true
			end

			if not hasKeyCard then
				sounderror:Play()
				text.Visible = true
				wait(3)
				text.Visible = false
			end
		end
	canhit = true
	end
end)

local cfv = Instance.new("CFrameValue")
cfv.Value = door:GetPivot()
cfv.Parent = door

cfv:GetPropertyChangedSignal("Value"):Connect(function()
	door:PivotTo(cfv.Value)
end)


function ease(x)
	local n1 = 7.5625
	local d1 = 2.75

	if (x < 1 / d1) then
		return n1 * x * x
	elseif (x < 2 / d1) then
		x -= 1.5/d1
		return n1 * (x) * x + 0.75
	elseif (x < 2.5 / d1) then
		x -= 2.25/d1
		return n1 * (x) * x + 0.9375
	else
		x -= 2.625/d1
		return n1 * (x) * x + 0.984375
	end
end


function closeDoor()

	if opened and not animationHappening then
		opened = false
		animationHappening = true

		local currentRot = door.PrimaryPart.Orientation.Y

		local closeStarted = tick()
		while true do
			local x = (tick() - closeStarted) / closeLength
			local rotOffset = ease(x) * -goalRot

			cfv.Value = CFrame.new(pos) * CFrame.Angles(0, math.rad((initialRot + goalRot) + rotOffset), 0)

			if x >= 1 then
				break
			end

			game:GetService("RunService").Heartbeat:Wait()
		end
		
		animationHappening = false
		prompt.Enabled = true
	end
end

function openDoor()
	
	if not opened and not animationHappening then
		opened = true
		animationHappening = true
		
		prompt.Enabled = false

		local openStarted = tick()
		
		while true do
			local x = (tick() - openStarted) / openLength
			local rotOffset = ease(x) * goalRot

			cfv.Value = CFrame.new(pos) * CFrame.Angles(0, math.rad(initialRot + rotOffset), 0)
			
			if x >= 1 then
				break
			end
			
			game:GetService("RunService").Heartbeat:Wait()
		end
		
		animationHappening = false
	end
end



prompt.Triggered:Connect(function(plr)
	
	local char = plr.Character
	if char and char:FindFirstChild("Humanoid") and char.Humanoid.Health > 0 then
		
		if char:FindFirstChild(keycardName) and char[keycardName]:IsA("Tool") then
		
			task.spawn(openDoor)
			task.wait(timeOpen)
			task.spawn(closeDoor)
		end
	end
end)

It seems you are unfamiliar with scripting. I don’t think you made this code. I recommend watching AlvinBlox’s beginner series if you want to learn to code.

I dont understand 100% the english :confused: so complexe when i need watch a video like that

I can’t help you much further. You need to be able to attempt to debug your code on your own and only go to the developer forum when you can’t figure it out.

About language barrier. You can look for tutorials in your language. More than likely there are (unless your language is not common). Or you might be able to use ai tools to dub over English videos. But that might take longer or cost money.

For the last error message you sent I will just say try using :WaitForChild(). When you have an error like that that something doesn’t exist you need to be able to debug it yourself with print() statements to see if it really doesn’t exist.

Good luck on your projects!


Btw solution,

-- localise the sound too*
local touchpart = game.Workspace:WaitForChild("Game"):WaitForChild("System"):WaitForChild("door"):WaitForChild("KeycardDoor"):WaitForChild("hitbox")
local player = game.Players.LocalPlayer
local text = player.PlayerGui.Notif.Text
local canhit = true

touchpart.Touched:Connect(function(hit)
	if canhit == true then
		canhit = false
		local name = hit.Parent.Name
		if hit and hit.Parent:FindFirstChild("Humanoid") then
			local hasKeyCard = false
			-- Check if the player has the key card
			local Tool = player.Backpack:FindFirstChild("KEYCARD") or player.Character:FindFirstChild("KEYCARD")
			if Tool then
				task.wait(1)
				soundpass:Play()
				hasKeyCard = true
			end

			if not hasKeyCard then
				sounderror:Play()
				text.Visible = true
				wait(3)
				text.Visible = false
			end
		end
	canhit = true
	end
end)

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