How do I detect when mouse is hovering over text

hey there fellow scripters

so i would like to know how to detect when the player’s mouse is hovering over a textlabel’s text (not the actual element, but the text of it)

and idk how to do that so uh if someone can help then thx :smiley:

2 Likes

TextLabel itself doesn’t provide pixel-perfect hover detection over just the text area—it treats the entire UI element (TextLabel.AbsoluteSize) as the interactive zone. There isn’t a built-in method to detect hovering only over the visible text portion inside the label. However, if you really want to approximate it, you can calculate the text bounds manually using TextService:GetTextSize() to get the size of the actual text, then compare the mouse position to that smaller area within the TextLabel.

Try this one:

local textLabel = script.Parent
local userInput = game:GetService("UserInputService")
local textService = game:GetService("TextService")
local runService = game:GetService("RunService")

local function isMouseOverText()
	local mousePos = userInput:GetMouseLocation()
	mousePos = Vector2.new(mousePos.X, mousePos.Y - 36) -- Offset topbar
	
	local textBounds = textService:GetTextSize(
		textLabel.Text,
		textLabel.TextSize,
		textLabel.Font,
		textLabel.AbsoluteSize
	)

	local labelPos = textLabel.AbsolutePosition
	local textPos = labelPos + (textLabel.AbsoluteSize - textBounds) / 2

	return mousePos.X >= textPos.X and mousePos.X <= textPos.X + textBounds.X and
		   mousePos.Y >= textPos.Y and mousePos.Y <= textPos.Y + textBounds.Y
end

runService.RenderStepped:Connect(function()
	if isMouseOverText() then
		print("Mouse is over the text!")
	end
end)

This setup checks each frame whether the mouse is inside the actual bounds of the rendered text. It’s not perfect (especially with text wrapping or scaling), but it’s your best bet for now.

2 Likes

first of all topbar is not 36px, second of all just use automaticsize and regular mouseEnter event?

yess you can use MouseEnter and MouseLeave on a TextLabel, but by default, those events trigger when the mouse enters the entire label area, not just the actual text.

If you want it to only trigger when hovering over the visible text itself, try enabling AutomaticSize = Enum.AutomaticSize.X

you do realize all you did was divide my suggestion in parts? all your code does is check if your mouse is within bounds of the labels textbounds, and thats what automaticsize would do to you, it would resize the label to textbounds removing any excess label area

Yes i replied to your idea only right? I’m just stating it again clearly. Is there anything wrong in it?

im talking about this, this makes no sense what you’ve said

yes it is by default. I’m just explaining why we need to enable automaticsize

reread your own message and come back later

local textLabel = script.Parent

local function InputBegan(InputObject : InputObject)
	if InputObject.UserInputType == Enum.UserInputType.MouseMovement then
		-- Code here, make a toggle bool because entering and leaving triggers the same enum.
	end
end

textLabel.InputBegan:Connect(InputBegan)

As long as your Text is the same size as your frame, you basically have no reason to overcomplicate a function such as this.

This can also be subsituted with MouseEnter and MouseLeave. Better yet, make a frame that is the exact same size as your text and check for Inputs on that.

you’re replying to the wrong person?

you are also overcomplicating this yourself lol, just use InputChanged

that’s the old topbar bob, roblox doesnt care to update a single number on their docs, go check coregui and make urself a believer

local textLabel = script.Parent

local newframe = Instance.new("Frame") 
-- Init unchangable properties
newframe.BackgroundTransparency = 1 -- Hides the background
newframe.BorderSizePixel = 0 -- Hides the border, might not be an issue

newframe.AnchorPoint = Vector2.new(0.5,0.5) -- Makes centering much easier, change if you don't have centered text.
newframe.Parent = textLabel
newframe.Position = UDim2.fromScale(0.5,0.5) -- Move to updateFunc if you plan to change your text alignments.

local function MouseEnter()
	print("Mouse Enter")
end

local function MouseLeft()
	print("Mouse Left")
end

local function updateNewFrame()
	if textLabel.TextWrapped then
		newframe.Size = UDim2.fromOffset(math.clamp(textLabel.TextBounds.X,0,textLabel.AbsoluteSize.X),math.clamp(textLabel.TextBounds.Y,0,textLabel.AbsoluteSize.Y))
	else
		newframe.Size = UDim2.fromOffset(textLabel.TextBounds.X,textLabel.TextBounds.Y)
	end
end

updateNewFrame()

textLabel.Changed:Connect(updateNewFrame)

newframe.MouseEnter:Connect(MouseEnter)
newframe.MouseLeave:Connect(MouseLeft)

This should do the trick for you.
This script makes a new frame and resizes it when you change the text.

If you plan to change alignment, please update the anchor and position above before doing so.

This comes with a small bug, if you have a overhang due to TextWrapped:

"I'm a string!
       Me too!"

The frame will still fill in that empty space.

3 Likes