UI collisions - how many % is overlapping?

Hello everyone, i was recently trying to create a grid inventory system where you can move stuff around. The problem is, when i was trying to create detection system for UI so you can pick up an item and release it where you want on the grid, it overlapped with other grids [check image]

my current collision detecting is just checking if the UI is overlapping or not but to make it work better i would have to check how many % is overlapped by this ui and pick the one with the biggest resoult. here is my current script:

local function CheckForCollisions(gui1, gui2) -- returns true or false
	local gui1_topLeft,gui1_bottomRight = gui1.AbsolutePosition, gui1.AbsolutePosition + gui1.AbsoluteSize
	local gui2_topLeft,gui2_bottomRight = gui2.AbsolutePosition, gui2.AbsolutePosition + gui2.AbsoluteSize

	return ((gui1_topLeft.x < gui2_bottomRight.x and gui1_bottomRight.x > gui2_topLeft.x) and (gui1_topLeft.y < gui2_bottomRight.y and gui1_bottomRight.y > gui2_topLeft.y))
end

for i, v in pairs(Inventory:GetChildren()) do
	if v:IsA("Frame") then
		local Resoult = CheckForCollisions(NewItem, v)
		print(Resoult, v.Name)
	end
end

(its only part of the script)

the resoult is 4 x true

let me know if you have an idea how could i make it work (idk how to check how much % is overlapping)

2 Likes

If the things being checked are the same size you have a special case where its:

overlapXPercent = math.max(0, 1 - math.abs((x1 - x2) / (2 * width) )  )
overlapYPercent = math.max(0, 1 - math.abs((y1 - y2) / (2 * height) )  )

overlapTotalPercent = overlapXPercent * overlapYPercent
1 Like

what do i replace x1 x2 and y1 y2 with

1 Like

x/y pixels of the first and second gui you’re checking

i mean its a square so i could just replace it with 0 ig?

There is the possibility of using a magnitude check on all the detected collisions to see which slot is closer (as long as they are all the same size).

After running the CheckForCollisions function, you could check if there has been a collision already and if so/or not compare their distance to the center of the box and set a value for it.

Example (not tested):

local CurrentOverwrite = nil
for i, v in pairs(Inventory:GetChildren()) do
	if v:IsA("Frame") then
		if CheckForCollisions(NewItem, v) then -- This Slot collided with our moving Slot.
			local DistanceToCenter = (v.AbsolutePosition - NewItem.AbsolutePosition).magnitude -- Check the distance from Slot to Moving Slot.
			if not CurrentOverwrite or DistanceToCenter < CurrentOverwrite[2] then -- If no Slot has been selected or this Slot is closer than the previous:
				CurrentOverwrite = {v, DistanceToCenter}	-- Set values in a table to remember Slot as well as its distance.
			end
		end
	end
end

if CurrentOverwrite then
	print("New Slot:", CurrentOverwrite[1])
else
	warn("No Slot was collided with.")
end

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