MouseLeave not always detecting

I’m having this problem where the mouse leaving a button isn’t always deleting a hover effect (happens when I move between buttons rapidly)

local function DeleteHover()
	if not CurrentHover then return end
	
	-- Destroy CurrentHover	
	CurrentHover:Destroy()
	CurrentHover = nil
end

ItemFrame.MouseEnter:Connect(function()
	if CurrentHover then		
		if CurrentHover.Name == ItemFrame.Name then return end
	end
	
	-- Do hover that follows mouse
	CurrentHover = HoverText:Clone()
	CurrentHover.Name = ItemFrame.Name
	CurrentHover.Text = ItemFrame.Name
	CurrentHover.Position = UDim2.new(0, Mouse.X + 20, 0, Mouse.Y + 36)
	
	CurrentHover.Shadow.Text = ItemFrame.Name
	
	CurrentHover.Parent = HUD
	
	CurrentHover.Size = UDim2.new(0, CurrentHover.TextBounds.X, 0, CurrentHover.TextBounds.Y)
end)

ItemFrame.MouseLeave:Connect(function()
	DeleteHover()
end)

local function MoveHover()
	if not CurrentHover then return end
	
	CurrentHover.Position = UDim2.new(0, Mouse.X + 20, 0, Mouse.Y + 36)
end

Mouse.Move:Connect(MoveHover)
1 Like

Whenever the mouse hovers on the main frame disable it too. I normally just do that to make sure this doesn’t happen.

MouseLeave isn’t the best.

You should not duplicate it every time you move, leave it outside of PlayerGui and insert it as needed.
This is a suggestion.

Any chance your issue correlates to these search results? Some results may also be able to help you.

https://devforum.roblox.com/search?context=topic&context_id=685550&q=mouseleave&skip_context=true

Looks more like an issue with your code and the return statements hopping out. Consider restructuring your code or taking a different approach.

MouseEnter and MouseLeave were unreliable at some point, but all the updates they’ve gotten in light of complaints and general Gui engine improvements have nulled that unreliability. Can’t say for sure though, I almost never use them anymore and use the Input_ events.

I’m not a huge stickler for memory consumption or anything but the way I would handle this nowadays is to have dedicated ToolTip TextLabels for each item and then move them around. The Gui ultimately isn’t static if you’re using tool tips so why not.

If you aren’t using ClipsDescendants: You can make the tool tip instances children of the ItemFrames themselves. Make them visible and move them to the mouse whenever it moves around, then hide the tool tip and don’t move the label if a user hovers off.

-- You can hypothetically just use one connection, but I like clarity, so I'm going to be using three.

local currentHover

local function moveToolTip(inputObject)
    -- MouseMovement caused InputChanged to fire and we have a tool tip hovered
    if inputObject.UserInputType == Enum.UserInputType.MouseMovement and currentHover then
        currentHover.Position = UDim2.fromOffset(Mouse.X + 20, Mouse.Y + 36)
    end
end

local function showToolTip(inputObject)
    -- MouseMovement caused InputBegan to fire
    if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
        ItemFrame.ToolTip.Visible = true
        currentHover = ItemFrame.InputChanged:Connect(moveToolTip)
    end
end

local function hideToolTip(inputObject)
    -- MouseMovement caused InputEnded to fire
    if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
        ItemFrame.ToolTip.Visible = false
        if currentHover and typeof(currentHover) == "RBXScriptConnection" then
            currentHover:Disconnect()
            currentHover = nil
        end
    end
end

ItemFrame.InputBegan:Connect(showToolTip)
ItemFrame.InputEnded:Connect(hideToolTip)
ItemFrame.InputChanged:Connect(moveToolTip)

If you are using ClipsDescendants: Just use one TextLabel to represent the tool tip and use the previous code to help you out. Per ItemFrame, a hover will cause the tool tip’s text to change and a leave will cause the tool tip’s text to go blank. Blank text won’t show but if you want to use the visibility property, then set it to true on hover and false on leave. You won’t have to bother with changing the text on leave if you use visible, just make sure the text is set before the visibility is for hovering. To move the tip, use UserInputService’s InputChanged or Mouse.Move then set the tool tip’s position.

-- Should be at the top with any other declarations
local toolTip = somewhere

local function moveToolTip(inputObject)
    -- Optional: add a condition only to pass the if statement if toolTip.Visible == true
    -- I wouldn't worry about connection management too much here. This is
    -- an inexpensive and constantly required operation. If you need to,
    -- disconnect it only when the shop closes and reconnect it when shop opens.
    if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
        toolTip.Position = UDim2.fromOffset(Mouse.X + 20, Mouse.Y + 36)
    end
end

local function showToolTip(inputObject)
    if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
        toolTip.Text = ItemFrame.Name
        -- toolTip.Visible = true
    end
end

local function hideToolTip(inputObject)
    if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
        -- toolTip.Text = ""
        toolTip.Visible = false
    end
end

ItemFrame.InputBegan:Connect(showToolTip)
ItemFrame.InputEnded:Connect(hideToolTip)

-- Do not do this for every ItemFrame, so keep it outside any loops.
UserInputService.InputChanged:Connect(moveToolTip)

I didn’t test any of this code, they are crude examples. Whether they work or not is beyond me. It should at least provide you a base line of how you can approach this problem, so heed the advice more than the code samples. Please.

1 Like

Seems to run a lot smoother. I’m getting problem regarding the text size constantly being lowered though.

local function ShowHover(inputObject)
	-- Do hover that follows mouse
	if inputObject.UserInputType ~= Enum.UserInputType.MouseMovement then return end
	
	HoverText.Text = ItemFrame.Name
	HoverText.Shadow.Text = HoverText.Text

	HoverText.Position = UDim2.new(0, Mouse.X + 20, 0, Mouse.Y + 40)
	print(HoverText.TextBounds.X)
	HoverText.Size = UDim2.new(0, HoverText.TextBounds.X, 0, HoverText.TextBounds.Y)
end

95

84

56 (x2)

45

39

35

34 (x12)
The text slowly gets smaller and smaller, until it gets to 34 and stays there. I want the textbutton to be sized based on the texts length (I don’t just wanna set the textbutton to have a X scale of 1)

And also a slight problem, when quickly moving between each button, at times the text just disappears and doesn’t re-appear until I leave completely and come back