Is there a more reliable method for detecting if a player is continuing to touch a part than Part.Touched and Part.TouchEnded?

I’m creating a game where a specific area switches the client’s music from clientsided to a jukebox that’s playing on the server. The script works as intended, but there’s an unfortunate issue where simply moving anywhere within the part that changes the music may fire TouchEnded, even if the player is very obviously still touching the part.

Is there an error with my method or is it an issue with the touch events? If it’s an issue with the touch events, what are some alternative methods I can use for the same, albeit reliable effect?

(This is a LocalScript on PlayerScripts that transfers the part to the workspace)

local TouchPart = script:WaitForChild("TouchDetectorForMusic")
local TweenService = game:GetService("TweenService")

local InteractiveObjects = game:GetService("Workspace"):WaitForChild("Interactive Objects")
local JukeboxSound = InteractiveObjects:WaitForChild("Jukebox Soundpart"):WaitForChild("Sound")

local DefaultJukeboxVolume = JukeboxSound.Volume
JukeboxSound.Volume = 0

local player = game.Players.LocalPlayer

TouchPart.Parent = workspace
local AudioChangeCommand = player:WaitForChild("PlayerGui"):WaitForChild("MasterScript"):WaitForChild("Audio Command Client-side")

local StereoTweenOn = TweenService:Create(JukeboxSound, TweenInfo.new(1,Enum.EasingStyle.Sine,Enum.EasingDirection.InOut), { Volume = DefaultJukeboxVolume })
local StereoTweenOff = TweenService:Create(JukeboxSound, TweenInfo.new(1,Enum.EasingStyle.Sine,Enum.EasingDirection.InOut), { Volume = 0 })

local debounce = false

TouchPart.Touched:Connect(function()
	if debounce == false then
		debounce = true
		AudioChangeCommand:Fire("mute")
		
		if StereoTweenOff.PlaybackState == 2 then
			StereoTweenOff:Cancel()
		end
		
		StereoTweenOn:Play()
	end
end)

TouchPart.TouchEnded:Connect(function()
	print("eventExit")
	print(debounce)
	if debounce == true then
		print("eventExit passed debounce")
		debounce = false
		AudioChangeCommand:Fire("unmute")
		
		if StereoTweenOn.PlaybackState == 2 then
			StereoTweenOn:Cancel()
		end
		
		StereoTweenOff:Play()
	end
end)

I would say region3 but i know nothing about that so I suggest:

1 Like

I’m going to look into this and see if it’s what I need! So far, looks promising.

1 Like

Region3 does have :GetPartsInRegion3(). However, it takes a load of processing power. In addition to that, Region3s cannot be rotated, and are fixed regions that have to be from one point to the other.
IF YOUR CASE INVOLVES PARTS WITH NO ROTATION AND ARE BRICKS, IGNORE ALL OF THIS AND USE REGION3s.

Luckily, ROBLOX has taken this in mind and has created two options:

BasePart:GetTouchingParts()
The most basic and straightfoward from all of them. Do this if you are not messing with CanCollide, collision groups, or any other wacky stuff like that. If you are, proceed to. the next method…

WorldRoot:GetPartsInPart(part, overlapParams)
The more complicated manner if you are dealing with CanCollide being off, or if you want to specify memory allocation for a specific number of scans, filtering descendants, etc… This one is a bit more complex and I only recommend it if you really know what you are doing.

Wrapping this in a RunService.Heartbeat after a .Touched event will give you the results you are looking for. Remember to disconnect it after what you are looking for is no longer present in the results, else you will have memory leaks and unecessary CPU usage.

2 Likes

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