Fed up with MouseEnter and MouseLeave not working? Here's a module for you!

Didn’t work for me. Could you be more specific in where to put each part of the script and module?

Make sure you require it first.

Then you gotta make the varible for the actuall events.

You would probably would want to use a local script and the the module script in replicated storage.

That should help.

Hi! I was wondering if anyone here has a solution to where it doesn’t keep detecting frames that aren’t visible on screen?

For example, the frame is still visible but the parent frames aren’t. Is there a way to detect or check if their parent frames are also visible?

1 Like

Any reason as to why this isnt working im so confused

local MouseOverModule = require(game.ReplicatedStorage.Packages.MouseOverModule)
local LeftIntHolder = game.StarterGui.MainUI.ScreenBorder.LeftInteractionHolder

local MouseEnter, MouseLeave = MouseOverModule.MouseEnterLeaveEvent(LeftIntHolder.MenuSideInteraction)

MouseEnter:Connect(function()
	LeftIntHolder.MenuSideInteraction:TweenSize(UDim2.new(0,75,0,75))
	print("mouse entered")
end)

MouseLeave:Connect(function()
	LeftIntHolder.MenuSideInteraction:TweenSize(UDim2.new(0,60,0,60))
	print("mouse left")
end)

it prints but does not tweensize

maybe because youre only changing the one in StarterGui (which is essentially the guis template when a player respawn) instead of the PlayerGui itself

1 Like
game:GetService("RunService").Heartbeat:Connect(function()
	--Check each UI object
	--All exit events fire before all enter events for ease of use, so check for mouse exit events here
	for _, Object in pairs(CurrentItems) do
		Object.MouseIsInFrame = IsInFrame(Object.UIObj)
		CheckMouseExited(Object)
	end

	--Now check if the mouse entered any frames
	for _, Object in pairs(CurrentItems) do
		if Object.UIObj.Visible == true then
			if Object.UIObj.Parent.Visible == true then
				CheckMouseEntered(Object)
			end
		end
	end
end)

This works, but I just realized if there’s another parent thats not visible it still detects your mouse. My solution to that was to add another if parent visible :face_with_diagonal_mouth:

If anyone is having the issue where MouseEnter fires even when the gui element isn’t visible, it’s as simple as returning false if the gui element isn’t visible.

local function IsInFrame(v)
	
	if not v.Visible then
		return false
	end

	local X = Mouse.X
	local Y = Mouse.Y

	if X>v.AbsolutePosition.X and Y>v.AbsolutePosition.Y and X<v.AbsolutePosition.X+v.AbsoluteSize.X and Y<v.AbsolutePosition.Y+v.AbsoluteSize.Y then
		return true
	else 
		return false
	end
end

Sorry for the bump, but i tweaked the module to work without player:GetMouse() (and cleaned it up a bit.)

-- module by @madattak, tweaked by @KingBlueDash

local UserInputService = game:GetService("UserInputService")

local CurrentItems = {}

--Private functions
local function IsInFrame(v)
	
	if not v.Visible then
		return false
	end
	
	local X = UserInputService:GetMouseLocation().X
	
	local Y = UserInputService:GetMouseLocation().Y

	if X > v.AbsolutePosition.X and Y > v.AbsolutePosition.Y
		and
		X < v.AbsolutePosition.X + v.AbsoluteSize.X
		and
		Y < v.AbsolutePosition.Y + v.AbsoluteSize.Y
	then
		
		return true
		
	else 
		return false
	end
end

local function CheckMouseExited(Object)

	if not Object.MouseIsInFrame
		and Object.MouseWasIn then -- if mouse was previously over object, fires the leave event.
		
		Object.MouseWasIn = false
		
		Object.LeaveEvent:Fire()
		
	end
	
end


local function CheckMouseEntered(Object)
	
	if Object.MouseIsInFrame and not Object.MouseWasIn then -- does the oppisite of the
		-- above function.
		
		Object.MouseWasIn = true
		
		Object.EnteredEvent:Fire()
		
	end
	
end

game:GetService("RunService").PreRender:Connect(function()
	
	-- checks each UI object.
	
	-- all exit events fire before all enter events for ease of use
	-- so check for mouse exit events here.
	
	for _, Object in pairs(CurrentItems) do
		
		Object.MouseIsInFrame = IsInFrame(Object.UIObj)
		
		CheckMouseExited(Object)
		
	end

	--Now check if the mouse entered any frames
	
	for _, Object in pairs(CurrentItems) do
		CheckMouseEntered(Object)
	end
	
end)

--Public functions

local module = {}

function module.MouseEnterLeaveEvent(UIObj)
	
	if CurrentItems[UIObj] then
		return CurrentItems[UIObj].EnteredEvent.Event,CurrentItems[UIObj].LeaveEvent.Event
	end     

	local newObj = {}

	newObj.UIObj = UIObj

	local EnterEvent = Instance.new("BindableEvent")
	
	local LeaveEvent = Instance.new("BindableEvent")

	newObj.EnteredEvent = EnterEvent
	
	newObj.LeaveEvent = LeaveEvent
	
	newObj.MouseWasIn = false
	
	CurrentItems[UIObj] = newObj

	UIObj.Destroying:Connect(function()
		
		EnterEvent:Destroy()  

		LeaveEvent:Destroy()   

		CurrentItems[UIObj] = nil
		
	end)

	return EnterEvent.Event,LeaveEvent.Event
	
end

return module