How to detect if cursor is on a GUI Button

Hello,
I’m Techyfied, a new UI Designer & scripter. I’m stuck with a script which is an important thing to make my Buttons look cool.

How would I detect if a LocalPlayer’s cursor is on a button? I want it to detect if a player’s cursor is on a button and if the cursor is on a button, the button color will change, and if it’s moved away, the button will turn back to it’s original look. I can do most of the part of the script except knowing how to detect if player’s cursor is on the button.

2 Likes

BasePlayerGui::GetGuiObjectsAtPosition

3 Likes

Could you tell me in details, I’m pretty new at scripting - specially the functions.

The api reference explains everything better (it literally explains how the function works lol)

Oh i just realized that was a link, im so dumb lol

There’s also another way: MouseEnter

4 Likes

For that, use MouseEnter and MouseLeave. MouseEnter when the cursor enters the GUI object area, and MouseLeave fires when the cursor leaves the GUI object.

2 Likes
local TweenService = game:GetService("TweenService")
local TweenAnimation = TweenInfo.new()

local Players = game:GetService("Players")
local Player = Players.LocalPlayer -- from a LocalScript
local Mouse = Player:GetMouse()
local Object = object -- YOUR OBJECT POSITION
local IsCurrentlyOn = false
local Prev = false

local function Update()
     if IsCurrentlyOn ~= Prev then
          if IsCurrentlyOn == true then
               local Tween = TweenService:Create(Object, TweenAnimation, {BackgroundColor3 = Color3.new(1,0,0)})
               Tween:Play()
          else
local Tween = TweenService:Create(Object, TweenAnimation, {BackgroundColor3 = Color3.new(0,0,0)})
               Tween:Play()
          end
     end
end

while wait() do
     local CheckObject = Player.PlayerGui:GetGuiObjectsAtPosition(Mouse.X, Mouse.Y)
     if CheckObject then
          if CheckObject == Object then-- add name of your button 
               IsCurrentlyOn = true
          else
               IsCurrentlyOn = false
          end
     end
end

I used BasePlayerGui:GetGuiObjectsAtPosition for it, I hope helped it.

I didn’t know there is another way to detect, I was only understanding MouseEnter & MouseLeave.

1 Like

Thanks, I’ll try it and let you know the result.

Didn’t work, can you help me find what’s the problem?

Script:

local TweenService = game:GetService("TweenService")
local TweenAnimation = TweenInfo.new()

local Players = game:GetService("Players")
local Player = Players.LocalPlayer -- from a LocalScript
local Mouse = Player:GetMouse()
local Object = script.Parent -- YOUR OBJECT POSITION
local IsCurrentlyOn = false
local Prev = false

local function Update()
     if IsCurrentlyOn ~= Prev then
          if IsCurrentlyOn == true then
               local Tween = TweenService:Create(Object, TweenAnimation, {ImageColor3 = Color3.new(255,255,255)})
               Tween:Play()
          else
local Tween = TweenService:Create(Object, TweenAnimation, {ImageColor3 = Color3.new(0,0,0)})
               Tween:Play()
          end
     end
end

while wait() do
     local CheckObject = Player.PlayerGui:GetGuiObjectsAtPosition(Mouse.X, Mouse.Y)
     if CheckObject then
          if CheckObject == Object then -- add name of your button 
               IsCurrentlyOn = true
          else
               IsCurrentlyOn = false
          end
     end
end

Parents:
image

(I am trying changing the ImageColor3 of the rounded image)

local TweenService = game:GetService("TweenService")
local TweenAnimation = TweenInfo.new()

local Players = game:GetService("Players")
local Player = Players.LocalPlayer -- from a LocalScript
local Mouse = Player:GetMouse()
local Object = script.Parent -- YOUR OBJECT POSITION
local IsCurrentlyOn = false
local Prev = false

local function Update()
     if IsCurrentlyOn ~= Prev then
          if IsCurrentlyOn == true then
               local Tween = TweenService:Create(Object, TweenAnimation, {ImageColor3 = Color3.new(255,255,255)})
               Tween:Play()
          else
local Tween = TweenService:Create(Object, TweenAnimation, {ImageColor3 = Color3.new(0,0,0)})
               Tween:Play()
          end
     end
end

while wait() do
     local CheckObject = Player.PlayerGui:GetGuiObjectsAtPosition(Mouse.X, Mouse.Y)
     if CheckObject then
          if CheckObject == Object then -- add name of your button 
               IsCurrentlyOn = true
          else
               IsCurrentlyOn = false
          end
     end
     Update()
end

oh my god, I forgot the Update() one.

Now try!

Sadly, it’s still not working. What about using MouseEnter and MouseLeave function?

Try utilizing the MouseEnter and MouseLeave functions in your script like so:

button.MouseEnter:Connect(function()
     -- change color when mouse enters
end)

button.MouseLeave:Connect(function()
    -- change color when mouse leaves
end)

Using loops could impact performance and is unnecessary for your use case. You can then use TweenService as you outlined to smoothly change the colors of the button.

5 Likes

There is a bug where when a another GuiButton overlaps any GuiObject that we need, placed in a ScreenGui of a smaller DisplayOrder , these events do not fire. This also happens when scrolling a ScrollingFrame .
I have a similar issue. I think GetGuiObjectsAtPosition would be a better solution, if properly optimized, if possible. Sorry for bumping a dead topic…