Do property changed events not fire for the PlayerMouse object?

For context, I’m trying to cut down on loops that run every-ish frame

I thought that I can do this for mouse stuff like so:

local LocalPlayer = game:GetService("Players").LocalPlayer
local Mouse = LocalPlayer:GetMouse()

Mouse:GetPropertyChangedSignal("Target"):Connect(function() -- Never fires?
	print("New target:", Mouse.Target)
end)

However, it never fires the event from my tests

I can live with this. Just wondering why it happens?

2 Likes

Mouse.Target actually performs a raycast in the background whenever you access it. (to determine the object its pointed at ofc)

Does your experience force you to use this method that often?

3 Likes

Maybe you could use mouse.move instead? I’m not sure of the purpose of your script, but this should work.

Ohh, at least I know why it happens now.

Kind of, I’m using this for cursor changes depending on who (or what) the mouse is pointed at; primarily allies/enemies or neutral things

Someone told me I can try putting a ClickDetector inside every player and track their .MouseHoverEnter or to just modify their MouseIcon property. It seems feasible, and probably better than a loop running every frame…

I could, but an entity can pop up on the cursor without it moving; which would make it not update.

1 Like

The Mouse object in Roblox doesn’t work like other objects where you can use GetPropertyChangedSignal to detect when a property changes. The reason your code doesn’t fire the event for Mouse.Target is because the Mouse object is because it doesn’t have property change signals in the usual sense.

The Mouse.Target property is constantly being updated by Roblox as you move your mouse around, but it doesn’t trigger any events when it changes. So even if you try to connect Mouse:GetPropertyChangedSignal("Target"), it’s simply not designed that way.

If you want to track when the target changes, the most straightforward way is to use a loop. I know loops aren’t ideal, but here’s a trick: you can use a loop that runs every frame to check if the target has changed, and only do something if it actually has. For example:

local RunService = game:GetService("RunService")
local LocalPlayer = game:GetService("Players").LocalPlayer
local Mouse = LocalPlayer:GetMouse()

local lastTarget = nil
RunService.RenderStepped:Connect(function()
    if Mouse.Target ~= lastTarget then
        lastTarget = Mouse.Target
        print("New target:", lastTarget)
    end
end)

Tell me if this helps you!

1 Like

ClickDetectors might be a great idea since you can add some attributes to determine if they are disabled (temporary disabling for scalability?).

Ends up in making your code slightly more readable if you do this correctly.

Good luck on your experience!

1 Like

You need Mouse.Move Function to get Targets

local LocalPlayer = game.Players.LocalPlayer
local GetMouse = LocalPlayer:GetMouse()

GetMouse.Move:Connect(function()
	print("New Target: " .. GetMouse.Target.Name)
end)

Every time you try and fetch a property, you are actually calling a function to find it’s value. Target happens to be a property that isn’t fetched by any other part of the engine, thus it’s value is never computed unless you call it, which is why your property changed signals do not get fired.

1 Like