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. 
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! 
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()