.Touched constantly being fired

Im making sound regions and it works however the .Touched function is constantly fired and so is my :Play() event. Ive tried adding if statements and it did not work. I dont know how to add a debounce if thats the way to do it.

script:

local sound = Instance.new("Sound")
local inArea = false
sound.Looped = true
sound.Parent = script
sound.Volume = 1

local char = script.Parent
local humanoid = char:WaitForChild("Humanoid")

local areasGroup = workspace:WaitForChild("Areas")


humanoid.Touched:Connect(function(touchedPart)	
	if touchedPart.Parent == areasGroup and inArea == false then
		sound.SoundId = touchedPart.Music.SoundId
		sound:Play()		
		inArea = true
		touchedPart.TouchEnded:Connect(function(touchEndedPart)			
			if touchEndedPart.Parent == char then 
				sound:Stop()
				inArea = false
			end
		end)
	end

This is intended behavior. TouchEnded, however, is kind of problematic, but there’s nothing that can be done simple enough.

Try separating the conditions into two if statements (since inArea acts as a debounce):

local sound = Instance.new("Sound", script)
local inArea = false

sound.Looped = true
sound.Volume = 1

local char = script.Parent
local humanoid = char:WaitForChild("Humanoid")

local areasGroup = workspace:WaitForChild("Areas")


humanoid.Touched:Connect(function(touchedPart)
	if (inArea) then
		return
	end
	
	if not (touchedPart.Parent == areasGroup) then
		return
	end
	
	sound.SoundId = touchedPart.Music.SoundId
	sound:Play()
	
	inArea = true
	
	local touchEndedConnection
	touchEndedConnection = touchedPart.TouchEnded:Connect(function(touchEndedPart)
		if touchEndedPart.Parent == char then 
			sound:Stop()
			inArea = false
			-- Remember to disconnect your events once they are no longer needed.
			-- Also, you can use "Once" instead to let a function only run once.
			touchEndedConnection:Disconnect() 
		end
	end)
end)

The sound seems to constantly do sound:Play() now, also could you explain “return” if possible because im trying to learn it and it’s very confusing.

Where is the part located? Maybe it’s touching with some other unrelated part, baseplate?

What you simply need is a debounce. Let me show you an example of one using your code.

local char = script.Parent
local humanoid = char:WaitForChild("Humanoid")
local debounce = false

local areasGroup = workspace:WaitForChild("Areas")


humanoid.Touched:Connect(function(touchedPart)	
	if touchedPart.Parent == areasGroup and inArea == false and debounce == false then
        debounce = true
		sound.SoundId = touchedPart.Music.SoundId
		sound:Play()		
		inArea = true
		touchedPart.TouchEnded:Connect(function(touchEndedPart)			
			if touchEndedPart.Parent == char and debounce == true then 
                debounce = false
				sound:Stop()
				inArea = false
			end
		end)
	end

A debounce is not the solution. Furthermore, .Touched isnt the solution. Add a clientscript that simply checks from time to time in which region3 the player is in. Each region should have a soundID attached to it. If oldRegion is not equal to currentRegion, then oldSound:Stop(), newSound:Play()

IMO, this is the best way to do it.

If you are too lazy to make region3 By script, create a part, Make it the size and the position you want to designate as the region, then put it in replicatedstorage, add the BiomeSound inside it, then create a function that creates a region3 for every biomeRegions inside replicated storage.

Thanks but this sounds complicated, I intended this to be a small detail for my lobby :confused:

1 Like

I mean Regions are pretty basics. You should learn them, it would really help you in your coding future:

1 Like

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