GetPropertyChangedSignal and read only values

I am currently trying to get when an assemblys root part changes, but GetPropertyChangedSignal isn’t firing, I assume because its read only? any ideas on how to get around this?

1 Like

Could it be where you set up the GetPropertyChangedSignal event? Your property, AssemblyRootPart I believe, is non-replicated, meaning if it’s changed on the client, the server wont notice the change. I tried it on another Read only property, AbsoluteSize on a textlabel, and it worked fine for me so GetPropertyChangedSignal can detect Read only property changes

no roblox needs to manually decide if the propertychangedsignal will fire, they for whatever reason decided not to do it for this one and a bunch of other read only properties.

my code is only running on server

Can you send me a place file with the stuff you’re using that has this issue so I can see what’s going on and if there’s a fix for it

RootTest.rbxl (24.3 KB)
Click run then try deleting different parts, nothing will happen

Im not exactly sure on how this works but read this [BasePart | Roblox Creator Documentation]

Since its read-only you won’t detect any changes

If you’re trying to listen to any changes made then make sure to use .Changed
and try to use :GetDescendants() instead of :GetChildren()

.Changed fires when any property changes, including position, also what do you mean by this???

Since this is a read-only property, you can’t have it in a script at all. So the best way to work around this is figuring out how the property is found, on the AssemblyRootPart page I was able to figure out a few things. It says in the article that getting the AssemblyRootPart property is the same as calling the :GetRootPart() method of the BasePart.

That’s only one piece to the puzzle though, we still don’t know how to know when this property is changed. So we need to find other properties that will effect the value of the AssemblyRootPart property. It says on the AssemblyRootPart page, “This property indicates the BasePart automatically chosen to represent the Assembly|assembly’s root part. It is the same part that’s returned when developers call GetRootPart().” We now know that the Parent of the BasePart effects the value of AssemblyRootPart. Below it states, " The root part can be changed by changing the RootPriority of the parts in the assembly." Now we know every property that effects the value of AssemblyRootPart

Here’s how we can apply all this information into a script:

local properties = {"Parent", "RootPriority"}; --Just for shortness
local AssemblyRootPart = part:GetRootPart();

for _, property in pairs(properties) do
	part:GetPropertyChangedSignal(property):Connect(function()
		AssemblyRootPart = part:GetRootPart();
	end);
end;

That was just an example, however it can it can be easily changed to suit your needs:

local properties = {"Parent", "RootPriority"};
local activeParts = workspace.ActiveParts:GetChildren();

local function connect(part, callback)
	local lastRootPart = part:GetRootPart();

	for _, property in pairs(properties) do
		part:GetPropertyChangedSignal(property)
			local newRootPart = part:GetRootPart();
			if newRootPart ~= lastRootPart then
				callback();
			end;
			lastRootPart = newRootPart;
		end);
	end;
end;

for _, part in pairs(activeParts) do
	connect(part, function()
		part.BrickColor = BrickColor.Random();
	end);
end;

Further Research:

the problem with this approach is its not just parent or root priority that can effect the root part, joints being broken on various parts in the assembly will also change the root part, for example on the place I attached, break the joints in the middle, the root parts will then change for 1 of the sides even through no parent was changed and no root priority was changed

for now ive settled on a while loop constantly checking the root part, this isnt the best way but i cant think of a better way