Stacked objects have weird physics, float until touched when the object below them is destroyed

I realised that it could be a combination of network ownership and physics weirdness and after testing a similar scenario in studio I think it is.

I think the reason the parts aren’t being woken correctly is that network ownership is being automatically set to the nearest player which is causing some odd behaviour.

when you spawn the ores try setting
MainPart:SetNetworkOwnership()
where MainPart is the part that any other parts in the ore are welded/constrained to (or you could do it for each part in the ore model)
(when called with no parameters SetNetworkOwnership sets network ownership to the server and prevents it being automatically moved to players)

this may cause parts to appear to move less smoothly on clients but I think it ought to work (you could probably wake the parts by setting their velocity which wouldn’t prevent network ownership being transferred but I don’t think it’s quite as neat a solution, and it’s more of a workaround)(I don’t think there is any way to directly wake a part)

4 Likes

Just tried both of these methods and neither seem to be working, or sometimes they do work and sometimes they don’t. It’s odd.

Are you setting the velocity on the parts you want to wake or on the parts you’re destroying?
it should be on the parts you want to wake and it should probably be after the Destroy is called.

1 Like

Oh, my bad, I was setting the velocity of the parts being destroyed and calling Wait before calling Destroy. Before trying methods to narrow it down to more specific parts, I just changed the velocity of every part in the folder I store the blocks in, and it worked! However, I’m experiencing small lag spikes when I destroy blocks, so I’ll look to some methods to make it affect less parts. I’m not sure how to only affect blocks in that stack, so I might just go for every block in a certain radius. If you know anything that’d be more efficient than that, do tell. :man_shrugging:

Not sure if it’ll be more efficient but here

This Should find all the parts of the ores that are touching the starting ore and and the parts of the ores that are touching those parts and so on. (sort of like how the bucket tool in a paint program keeps filling pixels of the same colour, the logic is pretty similar)

Change script.Parent on the first line to a part in the ore you’re destroying
and change “not CurrentPart.Anchored” to a check that the part is a part of an ore (as it is it’ll return any parts that aren’t anchored that are touching any of the connected ores)

You should also note that this will give a set of parts not the models that those parts are parented to and that it will include the parts of the starting ore in the set it gives you.

local StartingPart = script.Parent -- this should be which ever part you want to start at
local PartsTouching = StartingPart:GetTouchingParts() -- gets the parts that are touching the starting part
local PartsToCheck = {}
local PartsChecked = {}
local CurrentPart = nil
local PartsSet = {}
--Adds all the parts that the inital check found to the set of parts to check
for Key, Value in pairs(PartsTouching) do
	CurrentPart = Value
	PartsToCheck[Value] = true
end
while CurrentPart ~= nil do
	PartsChecked[CurrentPart] = true -- adds this part to the set of parts that has been checked
	PartsToCheck[CurrentPart] = nil -- removes this part from the set of parts that still need to be checked
	if not CurrentPart.Anchored then --This expression should be replaced by a check that the part is a part of an ore
		PartsSet[CurrentPart] = true -- adds the current Part to the PartSet
		PartsTouching = CurrentPart:GetTouchingParts() -- gets the parts that are touching the current part
		for Key, Value in pairs(PartsTouching) do
			if (not PartsChecked[Value]) and (not PartsToCheck[Value]) then -- checks if each part has already been checked
				PartsToCheck[Value] = true -- and adds it to the set if not
			end
		end
	end
	
	CurrentPart = nil
	--there might be a more efficent way to do this next part
	--sets current part to a part in the set PartsToCheck
	for Key in pairs(PartsToCheck) do
		CurrentPart = Key
		break
	end
end

for Part in pairs(PartsSet) do
	print(Part) -- do what you want to to each of the parts here
end
1 Like

After setting it up, I’m not sure if this works, or if I’m using it wrong. Looking at what’s printed, it doesn’t detect any touching parts. But, even if it doesn’t work, I’ve currently got it set up to change the velocity of every part in a 32 stud radius, and it’s working perfectly with no lag. Thank you for your help, you’ve been great! :grin:

I works in my test case, but if you’ve got a solution then it doesn’t matter.

edit: I’ve done some more testing and it seems that it’s quite particular about whether two parts count as touching so it might not be all that consistent

1 Like

Yup. Thanks again for your help, I couldn’t have done this without you.