How to prevent MouseEnter from being fired when a frame is above them?

Unsure if I should report this as a bug (would, but too lazy to make a repro atm) but as far as I’m aware this has always happened, and it’s incredibly infuriating, and not how I believe MouseEnter should work.

I have a bunch of buttons, each with MouseEnter events connected to them. However, notable flaws are that they still work even if a frame is above them, causing unwanted problems

Any possible solutions?? I don’t want to do

if not frame.Visible then

As I use the MouseEnter function is a variety of different scripts for just the 1 case of buttons here. Example being, 1 script handles the hover sound effect, another handles the hover frame info.

1 Like

Bumping this, I’m looking for a solution now… Were you able to find a solution @NinjoOnline ?

Second bump… Were any of you guys able to find a solution?

Dang unfortunately I don’t quite remember. It wasn’t an overall solution but just a case specific solution I think.

I think if you set Frame.Active to true, that should work.

That’s what I tried, and I’m sure he did too, but it didn’t work.

Is visible also true? That may be the problem.

Yes visible is on, active is on, and interactable is on, yet the frames below it still register MouseEnter

I wrote you some code. You’ll need to change it to fit your application though. Here’s how it works:

  • We keep track of all ‘depths’ (how deep a frame is nested)
  • We keep track of all hovered over frame
  • We select the highest hovered frame
  • When we leave it, we try select the next highest hovered frame (if there’s any left)
    49ea790af492bb944ec2f791dc61821a

local topFrame, topFrameDepth = nil, 0

local hovered = {}
local cached = {}

local function getFrameDepth(f)
	if not cached[f] then
		local depth = 0
		local parent = f
		repeat
			depth = depth + 1
			parent = parent.Parent
		until parent:IsA("ScreenGui") or not parent
		cached[f] = depth
	end
	return cached[f]
end

local function updateTopFrame()
	-- Sort hovered frames by depth in descending order
	table.sort(hovered, function(a, b)
		return getFrameDepth(a) > getFrameDepth(b)
	end)

	-- Set the new top frame
	if #hovered > 0 then
		local newTopFrame = hovered[1]
		local newTopFrameDepth = getFrameDepth(newTopFrame)

		if newTopFrame ~= topFrame then
			if topFrame then
				topFrame.BackgroundColor3 = Color3.new(1, 1, 1)
			end

			topFrame = newTopFrame
			topFrameDepth = newTopFrameDepth
			topFrame.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
		end
	else
		if topFrame then
			topFrame.BackgroundColor3 = Color3.new(1, 1, 1)
		end

		topFrame = nil
		topFrameDepth = 0
	end
end

for _, v in ipairs(script.Parent:GetDescendants()) do
	if v:IsA("Frame") then
		v.MouseEnter:Connect(function()
			if not table.find(hovered, v) then
				table.insert(hovered, v)
			end
			updateTopFrame()
		end)

		v.MouseLeave:Connect(function()
			local index = table.find(hovered, v)
			if index then
				table.remove(hovered, index)
			end
			updateTopFrame()
		end)
	end
end

1 Like