Touched event playing music stops after a few seconds

Hello, fellow developers. Today I made a script that detects when the player is in a region, displays a GUI, and plays music. However, when testing, the music plays for a few seconds and then just stops. I’ve heard about the unreliability of Touched and TouchEnded events, but is it really to the point where it’s almost unusable? Or am I doing something wrong? And yes, the GUI does show the entire time, it’s just the music.

Example script inside a region:

local Players = game:GetService("Players")
local event = game.ReplicatedStorage.Remotes:WaitForChild("ObjectiveRE")
local mission = script.Parent.Name
local objective = "Secure the stolen loot"
local touch = false

script.Parent.Touched:Connect(function(hit)
	local player = Players:GetPlayerFromCharacter(hit.Parent)
	
	if player then
		touch = true
		event:FireClient(player, mission, objective, touch)
	end
end)

script.Parent.TouchEnded:Connect(function(hit)
	local player = Players:GetPlayerFromCharacter(hit.Parent)

	if player then
		touch = false
		event:FireClient(player, mission, objective, touch)
	end
end)

LocalScript inside the GUI(which also contains the music):

local event = game.ReplicatedStorage.Remotes:WaitForChild("ObjectiveRE")
local text = script.Parent.ObjectiveFrame:WaitForChild("Objective")
local gameMusic = script.Parent.GameMusic

event.OnClientEvent:Connect(function(mission, objective, touch)
	local music = script.Parent.Music:FindFirstChild(mission)
	
	if touch == true then
		gameMusic:Stop()
		music:Play()
		text.Text = objective
	else
		music:Stop()
		gameMusic:Play()
		text.Text = "Get to a mission"
	end
end)

Any help would be greatly appreciated.

Thanks,
SpeakerDev

Have you done a print statement every time touch is lost? to see if you’re slightly clipping out? also if it’s just the music check the audio to see if there are any errors that would cause it or if it’s just not on a loop.

You could also try using region3s instead of parts to get more reliability if it’s just down to .touched not working correctly.

Okay, so it works fine as long as your level, but when you jump or walk over something, it prints:

  10:17:14.244  Touch ended  -  Client - Main:17
  10:17:14.245  Touch began  -  Client - Main:12
  10:17:14.245  Touch ended  -  Client - Main:17
  10:17:14.245  Touch began  -  Client - Main:12
  10:17:14.245  Touch ended  -  Client - Main:17
  10:17:14.245  Touch began  -  Client - Main:12
  10:17:14.246  Touch ended  -  Client - Main:17
  10:17:14.246  Touch began  -  Client - Main:12
  10:17:14.246  Touch ended  -  Client - Main:17
  10:17:14.246  Touch began  -  Client - Main:12
  10:17:14.247  Touch ended  -  Client - Main:17
  10:17:14.247  Touch began  -  Client - Main:12
  10:17:14.247  Touch ended  -  Client - Main:17
  10:17:14.248  Touch began  -  Client - Main:12
  10:17:14.346  Touch ended  -  Client - Main:17
  10:17:14.346  Touch began  -  Client - Main:12
  10:17:14.347  Touch ended  -  Client - Main:17
  10:17:14.347  Touch began  -  Client - Main:12
  10:17:14.347  Touch ended  -  Client - Main:17
  10:17:14.347  Touch began  -  Client - Main:12
  10:17:14.348  Touch ended  -  Client - Main:17
  10:17:14.348  Touch began  -  Client - Main:12
  10:17:14.348  Touch ended  -  Client - Main:17
  10:17:14.348  Touch began  -  Client - Main:12
  10:17:14.349  Touch ended  -  Client - Main:17
  10:17:14.349  Touch began  -  Client - Main:12
  10:17:14.349  Touch ended  -  Client - Main:17
  10:17:14.349  Touch began  -  Client - Main:12

I am definitely sure that the region stretches much higher than how high you jump. Is this a problem with the Touched event?

I’m not sure, try using a region3 which is just a box that you loop through what’s inside so assuming it’s big enough to not let you lapse out it should be fine.

wiki on region3’s: Region3 | Roblox Creator Documentation

I think the problem your having is that all parts of the character are activating the touch event head, feet, hands, etc…

so maybe filter the part to only allow the HumanoidRootPart

local players = game:GetService("Players")
local event = game.ReplicatedStorage.Remotes.ObjectiveRE

script.Parent.Touched:Connect(function(part)
	if part.Name ~= "HumanoidRootPart" then return end
	local player = players:GetPlayerFromCharacter(part.Parent)
	if player == nil then return end
	event:FireClient(player, mission, objective, true)
end)

script.Parent.TouchEnded:Connect(function(part)
	if part.Name ~= "HumanoidRootPart" then return end
	local player = players:GetPlayerFromCharacter(part.Parent)
	if player == nil then return end
	event:FireClient(player, mission, objective, false)
end)

Now it just does 4 prints:

  11:00:12.398  Touch ended  -  Client - Main:17
  11:00:12.398  Touch began  -  Client - Main:12
  11:00:12.483  Touch ended  -  Client - Main:17
  11:00:12.483  Touch began  -  Client - Main:12

…instead of 20.

strange it should only print 2 times and also is strange that it first prints Touch ended first

They likely have a memory leak somewhere.

Is the Part the player is touching at ground level?
I’ve used the same method you are using (Touched and TouchEnded), but my Touched Part is CanCollide off, sitting .2 studs above the ground, and is 8 studs high.

I lifted the part off the ground by a little bit and it broke. I assume it’s because part of the leg is touching it and the other part is not.

Memory leak? Please elaborate, I’ve never heard of this before. Looking it up brought me to the conclusion that you can’t even clean up memory leaks in Luau, just vanilla Lua.

But how big is the Part? I made mine large enough that the entire player moves through the Part (as I said, it’s 8 studs thick).

image_2022-08-09_162604038

Alright, I followed a tutorial on Region3 and made this script. The only problem is that now the objective text changes for about half a second and suddenly goes back to “Get to a mission”.

The new LocalScript inside ObjectiveGui:

local SoundRegionsWorkspace = game.Workspace:WaitForChild("Regions")

local Found = false

while wait(0) do

	for i, v in pairs (SoundRegionsWorkspace:GetChildren()) do

		Found = false
		local region = Region3.new(v.Position - (v.Size/2),v.Position + (v.Size/2))

		local parts = game.Workspace:FindPartsInRegion3WithWhiteList(region, game.Players.LocalPlayer.Character:GetDescendants())


		for _, part in pairs(parts) do
			-- Loop one by one through the parts table
			if part:FindFirstAncestor(game.Players.LocalPlayer.Name) then
				print("Player was found")
				Found = true
				break
			else
				Found = false
				print("Player was not found in region")
			end
		end

		if Found == true then
			-- Start playing some music
			if script.Parent.Music[v.Name].IsPlaying == false then
				script.Parent.GameMusic:Stop()
				script.Parent.Music[v.Name]:Play()
				script.Parent.ObjectiveFrame.Objective.Text = script.Parent.Objectives[v.Name].Value
				break
			end
		else
			script.Parent.Music[v.Name]:Stop()
			script.Parent.GameMusic:Play()
			script.Parent.ObjectiveFrame.Objective.Text = "Get to a mission"
		end

	end
end

What am I doing wrong? (Also, the music plays just fine, it’s just the GUI.)

Thanks,
SpeakerDev