Destructible models?

How do I make a model that is made up of multiple bricks destructible under forces(ex. explosions, rockets)
The classical way of doing this was making my models with studs and inlets and joints would be created automatically, but that does not work anymore.

I have tried using WeldConstraints, but sometimes they do not work as expected.

For example, this chimney is still floating, but it is not anchored.
Any help would be appreciated. (The welding was done by the qPerfectionWeld script first, and then I also made a custom script by myself, but they both did not work as I wanted them to)

I’m not sure but you could try and anchor everything, stud by stud, and then when a disaster touches unacnhor them? Like:

if hit.Name = “destroyable” then
hit.Anchored = false

Join Surface can help you with this

Just build your regular ol house piece by piece like legos
they auto connect
and you dont need to anchor them

What if I have a model that has already been built and I want it to be joined up like this. (The model is already made of tiny bricks)

For that you would have to use some kind of plugin

if you move the model with join surfaces on i think it welds everything together

1 Like

It does? I’m not sure, I don’t remember that it does

This code should weld the parts of the desired model.

local model = workspace.ModelToWeld

local function weldParts(partA, partB)
	local weld = Instance.new("Weld")
	weld.Part0 = partA
	weld.Part1 = partB
	weld.Parent = partA
end

local function arePartsTouching(partA, partB)
	local touching = false
	for _, part in ipairs({partA, partB}) do
		for _, otherPart in ipairs(part:GetTouchingParts()) do
			if otherPart == partA or otherPart == partB then
				touching = true
				break
			end
		end
		if touching then
			break
		end
	end
	return touching
end

local function weldModel(model)
	for _, partA in ipairs(model:GetDescendants()) do
		if partA:IsA("BasePart") then
			for _, partB in ipairs(model:GetDescendants()) do
				if partB:IsA("BasePart") and partA ~= partB and arePartsTouching(partA, partB) then
					weldParts(partA, partB)
				end
			end
		end
	end
end

weldModel(model)
game:GetService("ChangeHistoryService"):SetWaypoint("Weld Model")
1 Like

It does not work, when unanchored all of the bricks fall apart, possibly because gettouchingparts has a limit

function Weld(model)
	for i, part in ipairs(model:GetDescendants()) do
		if(part:IsA("BasePart")) then
			local rayOrigin = part.Position
			local up = part.CFrame.UpVector*500
			local right = part.CFrame.RightVector*500
			local forward = part.CFrame.LookVector*500
			local down = -up
			local left = -right 
			local back = -forward

			local dirs = {up, down, left, right, forward, back}
			local raycastParams = RaycastParams.new()

			raycastParams.FilterDescendantsInstances ={model}

			raycastParams.FilterType = Enum.RaycastFilterType.Include

			raycastParams.IgnoreWater = true
			for j, direction in ipairs(dirs) do
				local raycastResult = workspace:Raycast(rayOrigin, direction, raycastParams)
				local weld = Instance.new("WeldConstraint")
				if raycastResult then	
					if raycastResult.Instance:FindFirstChildOfClass("WeldConstraint") then
						
					end
					weld.Parent=part
					weld.Part0 = part 
					weld.Part1 = raycastResult.Instance
					raycastResult.Instance.Anchored = false
				end
			end
			part.Anchored = false
	
		end
	end


end

this is my script, it basically shoots raycasts and creates welds based off the results of the raycast. The model is anchored prior

The problem with my script is that it still has those floating parts like the chimney in the original post

I have just found out why my script did not work.
The script was based on using raycasts, which is fine, but I made their length way too large in every direction, therefore every part would get welded to the ground, and since the ground is immovable, the parts welded to it would be immovable as well. I fixed it so it only shoots a ray thats proportional to the size of the part
For anyone interested, here is the script that I made. It is a bit dodgy, so keep in mind that floating parts, not connected to any structure that this script welds, will become unanchored and fall.
To use it just put it into serverscriptservice and to any model you want to weld, add the Weld boolean attribute and set it to true

function Weld(model)
	for i, part in ipairs(model:GetDescendants()) do
		if not part:IsA("BasePart") then continue end

		local rayOrigin = part.Position
		local up = part.CFrame.UpVector*part.Size.Y
		local right = part.CFrame.RightVector*part.Size.X
		local forward = part.CFrame.LookVector*part.Size.Z
		local down = -up
		local left = -right 
		local back = -forward

		local dirs = {up, down, left, right, forward, back}
		
		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances ={model}
		raycastParams.FilterType = Enum.RaycastFilterType.Include
		raycastParams.IgnoreWater = true
		
		for j, direction in ipairs(dirs) do
			local raycastResult = workspace:Raycast(rayOrigin, direction, raycastParams)
			local weld = Instance.new("WeldConstraint")
			if raycastResult then	
				weld.Parent=part
				weld.Part0 = part 
				weld.Part1 = raycastResult.Instance
				raycastResult.Instance.Anchored = false
			end
		end
		part.Anchored = false

		
	end

end

for i, model in pairs(workspace:GetDescendants()) do
	if model:IsA("Model") and model:GetAttribute("Weld") then
		Weld(model)
	end
end

I see many instances where this would not work. As of right now you using a linear raycast which will miss a lot of parts. Instead you should base it off a max magnitude.

First, insert a script to your model,

script.parent:MakeJoints()

Then, test it and see if it works

(Disable your weld scripts)