Issue with MouseHoverLeave

I’m trying to make a “Highlight” system which gets activated upon the player moving their mouse over the object that has the highlight attached to it but, if the player keeps their mouse over the object with the highlight, equips any tool and moves their mouse off from the highlighted object, the highlight remains turned on and won’t get disabled until the player unequips the tool and hovers their mouse on and off the object again.

Here’s a video example:


(Sorry for the low quality)

This is the script used within the object (ServerScript):

local click = script.Parent
local ui = script.Parent.Parent.StatsPart.BillboardGui.CanvasGroup

click.MouseHoverEnter:Connect(function(plr)

	ui.Visible = true
	script.Parent.Parent.Highlight.Enabled = true

end)

click.MouseHoverLeave:Connect(function(plr)

	ui.Visible = false
	script.Parent.Parent.Highlight.Enabled = false

end)

You could use mouse.Hit instead. Have it check constantly in a loop, it would allow for more functionality then just mouse hover enter and mouse hover leave too.

After reviewing the API reference for both ClickDetector and Tool, I was unable to find any properties that may prevent a tool from interrupting ClickDetector.MouseHoverLeave and its related events. After reviewing similar posts, and developing my own consensus, it appears your only solution is to manually detect when the local player’s mouse hovers over the vending machine. You can achieve this with raycasting.

Normally, you’d use Mouse.Hit, but Roblox intends for its developers to interact with the user’s input devices through UserInputService. We can re-create Mouse.Hit with UserInputService fairly easily. Once we have the BasePart that’s beneath the player’s mouse, we can attempt to find the first ancestor of the Model class that contains a Highlight child. Once we have this, we can toggle its Highlight. Finally, we need to cache the current model so we can detect if the player changes models or is no longer hovering over one.

Altogether:

local UserInputService = game:GetService("UserInputService")


local Camera = workspace.CurrentCamera


local currentModel: Model?



local function getBasePartUnderMouse(): BasePart?
	local mouseLocation = UserInputService:GetMouseLocation()
	local ray           = Camera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
	local result        = workspace:Raycast(ray.Origin, ray.Direction * 1_000)

	if not result then
		return
	end

	return result.Instance
end

local function getModelWithHighlight(descendant: Instance): Model?
	while true do
		local model = descendant:FindFirstAncestorOfClass("Model") :: Model
		if not model then
			return
		end

		if model:FindFirstChildOfClass("Highlight") then
			return model
		end

		descendant = model
	end
end

local function onInputChanged(input: InputObject, gameProcessedEvent: boolean)
	if gameProcessedEvent then
		return
	end

	if input.UserInputType ~= Enum.UserInputType.MouseMovement then
		return
	end

	local basePart = getBasePartUnderMouse()
	if not basePart then
		return
	end

	local model = getModelWithHighlight(basePart)
	if model then
        --
		if currentModel and currentModel ~= model then
			currentModel.Highlight.Enabled = false
		end

		currentModel = model
		currentModel.Highlight.Enabled = true
	else
		if currentModel then
			currentModel.Highlight.Enabled = false
		end
	end
end



UserInputService.InputChanged:Connect(onInputChanged)

You’ll need to play around with the ray length as ClickDetector.MaxActivationDistance is no longer considered. That, or you can add your own distance check