GUI Layering Mouse Detection

I’m working on category navigation GUI inspired by The Sims 4.

Everything’s going great until I’ve ran into a mouse target problem. I’m using the MouseEnter event for the sample below. This creates an inaccurate selection problem, aswell.

I expected ZIndex layering would be the solution. The higher the ZIndex, the higher its priority, right? I’m not sure how Roblox currently decides what GUI is being hovered over but it sure is unreliable.

Is there a workaround to this problem and why doesn’t layering with ZIndex make a difference? (Please make this a thing Roblox :slight_smile: )

In case, you don’t know how it’s supposed to be:

Icons by @theloudscream Thank you.

2 Likes

You could check for whenever the mouse moves then use GetGuiObjectsAtPosition to detect if you’re hovering over the icons.

3 Likes

Took a while, but I got a solution:

the issue is the game thinks youre still hovering over the table while youre hovering over the lamp.
the solution is: keep track of your most recently hovered object, make all other objects youre currently ‘hovering’ white


hovering.rbxl (20.8 KB)

local imagesHovering = {}
local mostRecentHover = nil

function deselectImages()
	--color all the images in objectsHovering white
	for _, image in pairs(imagesHovering)do
		image.ImageColor3 = Color3.fromRGB(255,255,255)
	end
end

--gets called when a mouse enters an image label
function onMouseEnter(imageLabel)
	deselectImages()
	
	imageLabel.ImageColor3 = Color3.fromRGB(0,0,0)
	table.insert(imagesHovering, imageLabel)
	mostRecentHover = imageLabel	
end

--gets called when an the mouse has stopped hovering over an image label
function onMouseLeave(imageLabel)
	deselectImages()
	
	table.remove(imagesHovering, #imagesHovering)
	mostRecentHover = imagesHovering[#imagesHovering] 
	
	if mostRecentHover then
		mostRecentHover.ImageColor3 = Color3.fromRGB(0,0,0)
	end
end

--go make hover events for each child of the gui
for _, child in pairs(script.Parent:GetChildren())do
	if child:IsA("ImageLabel")then
		child.MouseEnter:Connect(function()
			onMouseEnter(child)
		end)
		
		child.MouseLeave:Connect(function()
			onMouseLeave(child)
		end)
	end
end
3 Likes

Thanks a lot for the response, your method helped me learn a lot.

One slight issue is when hovering over a new GUI object inside of a GUI object; this is too strange to explain, watch the video below:

I did some minor tweaking that uses the highest GUI object ZIndex to be the one being hovered over.

Here’s the code:

for _, button in pairs(whatever:GetChildren()) do
	if button:IsA("ImageButton") then
		
		local function HighestZIndexInList()
			local highest = 0
			local guiObject = nil
			
			for _, v in pairs(imagesHovering) do
				if v.ZIndex > highest then
					highest = v.ZIndex
					guiObject = v
				end
			end
			
			highest = 0
			return guiObject
		end
		
		local function deselectImages()
			for _, image in pairs(imagesHovering)do
				image.BackgroundColor3 = Color3.fromRGB(255,255,255)
			end
		end
		
		local function onMouseEnter(imageLabel)
			deselectImages()
			
			table.insert(imagesHovering, 1 ,imageLabel)
			HighestZIndexInList().BackgroundColor3 = Color3.fromRGB(255, 255, 75)
			mostRecentHover = imageLabel	
		end
		
		local function onMouseLeave(imageLabel)
			deselectImages()
			table.remove(imagesHovering, table.find(imagesHovering, imageLabel))

			mostRecentHover = imagesHovering[1]
			if mostRecentHover then
				mostRecentHover.BackgroundColor3 = Color3.fromRGB(255, 255, 75)
			end
		end
	
		button.MouseEnter:Connect(function()
			onMouseEnter(button)
		end)
		
		button.MouseLeave:Connect(function()
			onMouseLeave(button)
		end)

Finally, by using tables, the navigation GUI is a lot more reliable and consistent (Still got a few bugs to fix, though.) Edit: no more bugs, the video below is the final version.

Anyways, thank you so much for the help. :slight_smile:

3 Likes