Detecting if mouse is in frame

so i set up a tag with “Options” in each of my Option frames. i’m trying to detect if the mouse has entered the frame. i’ve heard you can use Mouse.Entered but i’ve also heard that it can cause issues.

i’m just looking for feedback on how to do this and is my set up for tags efficient or is it not. thanks a million!

local CollectionService = game:GetService("CollectionService")
local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local GuiService = game:GetService("GuiService")
local player = game.Players.LocalPlayer
local playerGui = player.PlayerGui

local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)

local function Hover()
	local mouseLocation = UserInputService:GetMouseLocation()
	local absoluteMousePos = mouseLocation - GuiService:GetGuiInset()
	local Guis = playerGui:GetGuiObjectsAtPosition(absoluteMousePos.X, absoluteMousePos.Y)
	
	for _, gui in Guis do
		for _, Options in pairs(CollectionService:GetTagged("Options")) do
			if gui == Options then
				print(Options.Name)
				--local MoveTween = TweenService:Create(Options, tweenInfo, )
			end
		end
	end
end

UserInputService.InputChanged:Connect(function(input, gameProcessed)
	if gameProcessed then return end
	Hover()
end)

I don’t believe this is a very optimal way to detect if a mouse is in frame, since it overcomplicates things greatly by performing so many checks. I highly suggest using the frames’ MouseEntered event. If the “Mouse.Entered” event you’ve expressed concerned about is this event, I wouldn’t worry unless you need to get the exact position where the mouse enters, as the documentation states.

If you really want to avoid using MouseEntered, I would at least remove the nested loop (ie. the loop starting with “for _, Options in pairs(CollectionService:GetTagged("Options")) do”) by making use of the Instance:HasTag method instead of searching through an entire table of all objects with the Options tag. It might looks something like replacing

for _, Options in pairs(CollectionService:GetTagged("Options")) do
	if gui == Options then
		print(Options.Name)
	end
end

with a much simpler

if gui:HasTag("Options") then
    print(gui.Name)
end

because gui should be the same as Options and, therefore, it wouldn’t matter whether you printed gui.Name or Options.Name.

If my above assumption is incorrect as well, one last optimization could be to use table.find. You’ll still end up with what is essentially a nested loop, but at least you won’t iterate through all the objects in pairs(CollectionService:GetTagged("Options")) if you find it early on.

1 Like

thanks mate, that was very helpful. :slight_smile:

yeah perhaps i was being a little over analytical. i did it with MouseEntered, MouseLeave after all.

i can’t get any better than this atm honestly. i appreciate the help a lot once again, cheers! :call_me_hand:

local CollectionService = game:GetService("CollectionService")
local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local GuiService = game:GetService("GuiService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local player = game.Players.LocalPlayer
local playerGui = player.PlayerGui

local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)

local function Hover()
	for _, option in pairs(CollectionService:GetTagged("Options")) do
		if option:IsDescendantOf(ReplicatedStorage) then continue end
		if option:IsA("GuiObject") then

			-- Avoid duplicate connections
			if not option:GetAttribute("HoverConnected") then
				local originalSize = option.Size
				local SizeMultiplier = 0.075

				option.MouseEnter:Connect(function()
					local goal = {Size = UDim2.new(originalSize.X.Scale + SizeMultiplier, 0, originalSize.Y.Scale + SizeMultiplier, 0)}
					local hoverTween = TweenService:Create(option, tweenInfo, goal)
					hoverTween:Play()
				end)
				
				option.MouseLeave:Connect(function()
					local goal = {Size = originalSize}
					local leaveTween = TweenService:Create(option, tweenInfo, goal)
					leaveTween:Play()
				end)

				option:SetAttribute("HoverConnected", true)
			end
		end
	end
end

Hover()