How do you implement the following system:

How do you make it that whenever the player touches a part, the sound plays once, and when the part is untouched and then touched again, the sound plays once again.

2 Likes

Considering that you have already created the part and the sound, you could use a script like this as an example:

local part = game.Workspace.Part -- Replace "Part" with the actual name of your part
local sound = game.Workspace.Sound -- Replace "Sound" with the actual name of your sound

local hasTouched = false

part.Touched:Connect(function(hit)
    local character = hit.Parent
    local humanoid = character:FindFirstChild("Humanoid")

    if humanoid and not hasTouched then
        hasTouched = true
        sound:Play()
    end
end)

part.TouchEnded:Connect(function(hit)
    local character = hit.Parent
    local humanoid = character:FindFirstChild("Humanoid")

    if humanoid then
        hasTouched = false
    end
end)

Now, the sound will play only once when the player touches the part, and it will play again if the part is untouched and touched again.

1 Like

I’ll give it a try and see if it works

edit: Nope, not working. Whenever I touch the part, the sound keeps playing multiple times

1 Like

I see no reason why this wouldn’t work.

Possible solutions I thought of:

  • Try making the part collision off, maybe the character animations are making it stop touching?
  • Make sure the sound is not looped
  • Add a print into the TouchEnded to test when it stops touching and try to find a solution based on that

If none of those work lmk and I’ll try to figure it out.

2 Likes

Okay I’ll give them a try

edit: what do you mean by " collision off " ? Should I disable collisions?

1 Like

On the part set CanCollide to false.

1 Like

I did everything and still not working. The sound keeps playing multiple times when the part is touched

1 Like

Alright, let me do some changes:

local part = game.Workspace.Part -- Replace "Part" with the actual name of your part
local sound = game.Workspace.Sound -- Replace "Sound" with the actual name of your sound

part.Touched:Connect(function(hit)
    local character = hit.Parent
    local humanoid = character:FindFirstChild("Humanoid")

    local hasTouched = false -- Move the variable declaration inside the event function

    if humanoid and not hasTouched then
        hasTouched = true
        sound:Play()
    end
end)

part.TouchEnded:Connect(function(hit)
    local character = hit.Parent
    local humanoid = character:FindFirstChild("Humanoid")

    if humanoid then
        hasTouched = false
    end
end)

With this change, the hasTouched variable will be reset to false every time the Touched event is triggered, allowing the sound to play again when the part is touched again, not multiple times I guess.

1 Like

It’s still not working

[ 30 letters ]

1 Like

I found the issue and I’ll edit this message with the code when I’m finished.

Sorry it’s a bit complicated but it does the job.
The part will need to have CanCollide off otherwise the character’s feet will keep triggering it every time they move.

local Part = script.Parent -- Replace with your part
local Sound = script.Sound -- Replace with your sound

local Cooldown = 1

local TouchedCharacter = nil
local OnCooldown = false

local function IsCharacterTouching(Character)
	local TouchingParts = Part:GetTouchingParts()
	local IsTouching = false
	
	--Loop through touching parts
	for _, Part in TouchingParts do
		--If the part is in the character
		if Part.Parent == Character then
			IsTouching = true
			break --End loop early
		end
	end
	
	return IsTouching
end

Part.Touched:Connect(function(hit)
	local Character = hit.Parent
	local Humanoid = Character:FindFirstChild("Humanoid")

	if Humanoid and not TouchedCharacter and not OnCooldown then
		TouchedCharacter = Character
		Sound:Play()
	end
end)

Part.TouchEnded:Connect(function(hit)
	local Character = hit.Parent
	local Humanoid = Character:FindFirstChild("Humanoid")

	if Humanoid and IsCharacterTouching(TouchedCharacter) == false then
		TouchedCharacter = nil
		
		OnCooldown = true
		task.wait(Cooldown) --Wait for cooldown
		OnCooldown = false
	end
end)
1 Like

i’ll give it a try

Edit: Yes, it’s finally working

Thank you very very much:)))

2 Likes

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