Touched fires twice problem

So, I made a game where you have to merge balls. The balls merge when two of the same color touch eachother, but the problem is that when two balls touch eachother they both fire the function that gives the player their currency. How can I make it happend for one ball only?

clone.Touched:Connect(function(hit)
	if hit:GetAttribute("Ball") == clone:GetAttribute("Ball") then
		local shiny = 0
		if hit:GetAttribute("Shiny") == true then
			shiny += 1
		end
					
		if clone:GetAttribute("Shiny") == true then
			shiny += 1
		end
					
		hit:Destroy()
		merge(clone:GetAttribute("Ball") + 1, clone, shiny)
	end
end)
1 Like

You can try adding a debounce
should be something like:

local debounce = false

clone.Touched:Connect(function(hit)
    if debounce then
        return
    end

    if hit:GetAttribute("Ball") == clone:GetAttribute("Ball") then
        debounce = true

        local shiny = 0
        if hit:GetAttribute("Shiny") == true then
            shiny += 1
        end

        if clone:GetAttribute("Shiny") == true then
            shiny += 1
        end

        hit:Destroy()
        merge(clone:GetAttribute("Ball") + 1, clone, shiny)

        wait(0.1)
        debounce = false
    end
end)

That is not going to work if I have 4 balls and 2 pairs collide at the same time.

you can make make each ball give half the currency like if the player should get 10 then each ball will give him 5 because 5x2 = 10

Debounce should work but should be this specific debounce with a global obserber script (bindable event) which has worked for this other person also working on a merge game.

I think it would be better if you had a handler that handles ball collisions instead of every ball doing its own thing. Basically, every time ball A touches ball B they both call the handler and then the handler would realize it was called twice for the same action and then it would do whatever you wanted it to do.

local BallCollisionHandler = {}

local CollisionMemory = {}

local function CompareItems(ItemA, ItemB)
	table.sort(ItemA)
	table.sort(ItemB)

	for i = 1, #ItemA do
		if ItemA[i] ~= ItemB[i] then
			return false
		end
	end

	return true
end

local function RemoveCollisionFromMemory(Collision)
	for i = #CollisionMemory, 1, -1 do
		if CompareItems(Collision, CollisionMemory[i]) then
			table.remove(CollisionMemory, i)
		end
	end
end

local function DoSomething()
	-- Do whatever you want to happen when two balls collide
	print("A collision was detected!")
end

local function CheckForSimilarCollisions(Collision)
	
	local IsSimilarCollisionFound = false
	
	for i, item in ipairs(CollisionMemory) do
		
		IsSimilarCollisionFound = CompareItems(Collision, item)
		
		if IsSimilarCollisionFound then
			DoSomething()
			RemoveCollisionFromMemory(item)
			return
		end
	end
	
	if IsSimilarCollisionFound == false then
		table.insert(CollisionMemory, Collision)
	end
end

function BallCollisionHandler.AddCollisionToMemory(BallA, BallB)
	local Collision = {BallA, BallB}
	CheckForSimilarCollisions(Collision)
end

return BallCollisionHandler

If youre planning to use this, put it in a module script. Also, i havent tested it so if it doesnt work lmk.

Have one script that manages all the collisons. Then you can have something the prevents both of them colliding with each other.

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