How to play Non-Looped music when touching a part?

Hello! I’m still new at scripting so i barely know how to code, Anyway i’m trying to make a piano where it plays the notes when u walk on that note! my goal is when i touch a part, an audio plays and when it finish playing, it won’t play again unless you stop touching the part and touch it again

The issue is that when i touch a part and stay on it the audio keeps looping after finishing even with the option (Loop OFF) and i need help of how can i make an audio plays once every touch

I tried a script i found in the tool box and here is it:

-- declarations

local head = script.Parent
local sound = head:findFirstChild("Victory")

function onTouched(part)
	local h = part.Parent:findFirstChild("Humanoid")
	if h~=nil then
sound:play()
if part.Parent:findFirstChild("Torso"):findFirstChild("roblox").Texture == nil then return end
part.Parent:findFirstChild("Torso"):findFirstChild("roblox").Texture=""
	end
end

script.Parent.Touched:connect(onTouched)

I really appreciate any help to solve this problem!

The reason why it is looping is because there is no debounce (aka cooldown). When there is no debounce it means that the Touched event will register many amount of times and that will get the sound to continue playing until the humanoid stops touching the part.

local head = script.Parent
local sound = head:findFirstChild("Victory")
debounce = 0 -- Needs to be global

function onTouched(part)
	local h = part.Parent:findFirstChild("Humanoid")
	if h~=nil then
		if debounce == 0 then
			debounce = 1      
			sound:play()
			if part.Parent:findFirstChild("Torso"):findFirstChild("roblox").Texture == nil then
				return 
			end
			part.Parent:findFirstChild("Torso"):findFirstChild("roblox").Texture=""
			wait() --Set the cooldown to however much time you want
			debounce = 0
		end
	end
end

script.Parent.Touched:connect(onTouched)

This should stop the music playing many amount of times.

1 Like

Thank you so much! Working fine :smiley:

1 Like

This script looks about a decade old (full of deprecated methods/bad code habits), here’s a revamped up to date version which I recommend you use instead.

local players = game:GetService("Players")

local part = script.Parent
local sound = part:WaitForChild("Victory")

local debounce = false

local function onTouched(hit)
	if debounce then
		return
	end
	
	local hitModel = hit:FindFirstAncestorOfClass("Model")
	if hitModel then
		local hitPlayer = players:GetPlayerFromCharacter(hitModel)
		if hitPlayer then
			debounce = true
			sound:Play()
			sound.Ended:Wait()
			debounce = false
		end
	end
end

part.Touched:Connect(onTouched)

Note we don’t need to call “wait()” to delay for an arbitrary length of time, we simply wait for the “Ended” event to fire on the “Sound” instance, this event fires whenever a full play-through of the audio track occurs.

1 Like

Wow, thank you so much, i’m still a beginner at scripting and i really appreciate your work <3