I would recommend using :GetPropertyChangedSignal(), as it’s more performant than .Changed in most cases - the former only fires when the specific property you want to monitor changes, whereas the latter fires if any property of the object is changed. You don’t want to run a function if it’s not going to change anything, which is the most likely outcome if the property/properties that function depends on haven’t changed.
The difference in these two handles is the specificity.
Instance.Changed is an event you can connect to like any other event using :Connect. If you’re unfamiliar with this use, you’re basically telling the computer to do something (the applied function) when something else (the event) happens. A good example is the following:
Every time a player joins the game, their name is printed to the console. (PlayerAdded is the event, the code wrapped inside the :Connect() statement is the function that is executed. (p is the player object passed by the event, but that isn’t relevant to this question.)
:GetPropertChangedSignal() on the other hand is not an event, but a method. The Changed event gets fired every time something on the Instance you’re using it on is changed. You can use :GetPropertyChangedSignal(“PropertyName”) to retrieve an event that gets fired only when the supplied property is changed. This might be used for executing code when a player’s character is regenerated (Player:GetPropertyChangedSignal("Character"):Connect(function() end)), though this is bad practice as dedicated event already exists for that under the Player object. (Player.CharacterAdded)
To summarize, Changed is an event that fires every time something on the instance it is used on changes. :GetPropertyChangedSignal() returns an event that fires every time the specific property is changed.
You can generally interchange them, though it does depend on the situation which is more efficient. For checking when an IntValue or StringValue’s value is changed, using Changed is fine as the other properties generally do not change.
The greatest difference between .Changed and :GetPropertyChangedSignal is that .Changed runs every time a property is changed.
Let’s say we were making a tween:
local object = Instance.new("Part")
object.Anchored = true
object.Parent = workspace
-- What I want to smoothly change in this tween
local Goal = {
Position = Vector3.new(10, 10, 10);
Size = Vector3.new(10, 10, 10);
Transparency = 1;
Reflectance = 0.5;
}
local Tween = game:GetService("TweenService"):Create(object, TweenInfo.new(5), Goal)
Tween:Play()
If I wanted to track just the Position, Changed would be a bad choice to do this because it will fire for all the other properties you don’t want to track (like Size, Transparency, and Reflectancy), and it can cost you performance. Instead, I can use the :GetPropertyChangedSignal function to return the event that listens for Position only.
local t = tick()
object:GetPropertyChangedSignal("Position"):Connect(function()
print("The part is currently at Position: " .. object.Position .. "." )
print("Time elapsed: " .. tick() - t)
end)
For Value items, it is useless using :GetPropertyChangedSignal as there are only 3 properties, and almost always only one property changes, which is of course the Value. Though it is good practice to use :GetPropertyChangedSignal, it is not necessary to use it in this case.
Both version fire when the Position property changes (provided GetPropertyChangedSignal() was supplied with “Position”), don’t know exactly how it works with the subproperties. If any of the axis of a Position change, the Position itself changes and the signals will get fired.