HoverOverhaul
It’s just a really short remake of MouseLeave and MouseEnter (112 lines) but it actually works properly.
Resisting the urge to call it Hoverhaul
There’s also support for BaseParts and MouseHovering/MouseNotHovering stuff too.
I’ll just paste the code here, or you can get it from the link below. I appreciate feedback because I mostly made this for fun!
I don’t really expect anyone to actually use this since there are other alternatives and it’s really easy to make.
Code
-- @FloofyNezzled | HoverOverhaul
local Hover = {}
if game:GetService("RunService"):IsServer() then
error(string.format("Cannot use %s in a server script!", script.Name))
end
local mouse = game:GetService("Players").LocalPlayer:GetMouse()
local function hovering(obj : GuiBase | BasePart)
if obj:IsA("GuiBase") then
local posX = obj.AbsolutePosition.X
local posY = obj.AbsolutePosition.Y
local totalX = posX + obj.AbsoluteSize.X
local totalY = posY + obj.AbsoluteSize.Y
return mouse.X >= posX and mouse.Y > posY and mouse.X <= totalX and mouse.Y <= totalY
else
return mouse.Target and mouse.Target == obj
end
end
local function signal(sig : RBXScriptSignal, fn : () -> ())
local breakable = false
local signal = sig and sig:Connect(fn) or function()
while true do
if breakable then break end
task.wait()
fn()
end
end
if not sig then
task.spawn(signal)
end
return {Disconnect = function()
if signal:IsA("RBXScriptSignal") then
signal:Disconnect()
else
breakable = true
end
end, ChangeFunction = function(newFn : () -> ())
if signal:IsA("RBXScriptSignal") then
signal:Disconnect()
signal = sig:Connect(newFn)
else
breakable = true
signal = function()
while true do
if breakable then break end
task.wait()
fn()
end
end
task.spawn(signal)
end
end}
end
function Hover.MouseEnter(obj : GuiBase | BasePart, fn : () -> ())
local canEnter = true
local signal = signal(mouse.Move, function()
if hovering(obj) and canEnter then
canEnter = false
fn()
elseif not hovering(obj) then
canEnter = true
end
end)
return signal
end
function Hover.MouseLeave(obj : GuiBase | BasePart, fn : () -> ())
local canLeave = true
local signal = signal(mouse.Move, function()
if not hovering(obj) and canLeave then
canLeave = false
fn()
elseif hovering(obj) then
canLeave = true
end
end)
return signal
end
function Hover.MouseHovering(obj : GuiBase | BasePart, fn : () -> ())
local signal = signal(nil, function()
if hovering(obj) then
fn()
end
end)
return signal
end
function Hover.MouseNotHovering(obj : GuiBase | BasePart, fn : () -> ())
local signal = signal(game:GetService("RunService").RenderStepped, function()
if not hovering(obj) then
fn()
end
end)
return signal
end
return Hover
Preview
Functions and usage
MouseEnter(obj, function)
MouseLeave(obj, function)
MouseHovering(obj, function)
MouseNotHovering(obj, function)
Example code:
local Hover = require(game:GetService("ReplicatedStorage").HoverOverhaul)
Hover.MouseEnter(label, function()
label.BackgroundColor3 = Color3.new()
end)
Hover.MouseLeave(label, function()
label.BackgroundColor3 = Color3.new(1, 1, 1)
label.BackgroundTransparency = 0
end)
Limitation I found: When using ScrollingFrames, it detects hovers on ui elements that aren’t in focus. Don’t know how to fix this.