Touched event is being detected too many times, how do I make sure only one touch is detected?

The script below works pretty well, although sometimes it still detects more than one touch. The first block is meant to stop it from entering the same player twice but as seen in the GIF it fails from time to time.

function foundInList(player)
	for _,target in ipairs(touching) do
		if target == player then
			return true;
		end
	end
	return false;
end
part.Touched:connect(function(hit)
    if not foundInList(player) then
	    table.insert(touching, player)
            local slot = template:Clone()
	    slot.Parent = game.Workspace.ListOfPlayers.SurfaceGui
		-- fancy stuff
    end
end)

The on touched event at first seemed useful in this situation but because of the amount of time if detects the on touch I’m looking to switch over to detecting if the player is within the are or not instead. Before I go to that I want to see if this can be fixed. Is there any way to prevent what is happening?

robloxapp-20200720-2147468 (1)

1 Like

table.find(tableName,player) works the same as your function. try that instead

1 Like

Your code seems correct, is there any other code that you fail to post or any other script interacting with the part? otherwise it shouldn’t be detecting more then once assuming your not removing the player from the table anywhere

1 Like

Does it occur if you add a debounce? I didn’t look at it too much, but it could be due to the process taking too long to add the player to the list.

Edit:
This is what I mean

local debounce = false
part.Touched:connect(function(hit)
if not debounce then
    debounce = true
    if not foundInList(player) then
	    table.insert(touching, player)
            local slot = template:Clone()
	    slot.Parent = game.Workspace.ListOfPlayers.SurfaceGui
		-- fancy stuff
    end
    debounce = false
end)
1 Like

While a debounce is a correct answer, I feel that that disconnecting the touch event is better. It would also prevent any memory leaks if that’s possible in this context.

@salmonbear242, here is some code you can use.

function foundInList(player)
    for _, target in ipairs(touching) do
        if target == player then
            return true
        else
            return false
    end
end
local touch — you have to define it before you can disconnect the event in the code’s scope.
touch = part.Touched:Connect(function(hit)
    if not foundInList(player) then
        table.insert(touching, player)
        local slot = template:Clone()
        slot.Parent = workspace.ListOfPlayers.SurfaceGui
        — fancy stuff
    end
    touch:Disconnect() — this is where we disconnect the event to stop it from firing
end)

You can learn more about event disconnection here: Documentation - Roblox Creator Hub

It provides a touch event example that would definitely help you.

Good luck on whatever you’re working on and never give up!

1 Like

From what I have tested (and it is a very bare bones and not a super official test.)

How I tested
local check = 0
local cheese
cheese = script.Event.Event:Connect(function ()
	if check > 0 then cheese:Disconnect() print("Disconnected") end
	check = check + 1
	while true do wait(1) print("wallet") end
end)

script.Event:Fire()
script.Event:Fire()

The print statements continue even after Disconnected is printed.

I have come to the conclusion that the function still runs if you are inside of it already, and that does not help the situation that the main post is in. Sure disconnecting would help, but you have to be careful how you do it. From what I have found doing this test, I would suggest adding the debounce without setting it back to false at the end. Inside of the if statement you then can disconnect the event.

I would suggest a combination of my answer and Kai's.
local touch — you have to define it before you can disconnect the event in the code’s scope.
local debounce = false
touch = part.Touched:Connect(function(hit)
if not debounce then
    debounce = true
    if not foundInList(player) then
        table.insert(touching, player)
        local slot = template:Clone()
        slot.Parent = workspace.ListOfPlayers.SurfaceGui
        — fancy stuff
    end
    touch:Disconnect() — this is where we disconnect the event to stop it from firing
end
end)

Though there always may be a better way, and I am open to more suggestions.

@xKaihatsu and @landon90

Thank you for your contributions. After I implemented your changes I was still having trouble with some of the other aspects in-game that relied on the touch event. I ultimately decided to not use the touch event and opt for a plugin called Zone+, which has it’s own player added events without needing a debounce. I do thank you for trying to help though.

@xKaihatsu, I won’t give up! :100:

3 Likes