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)
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")
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
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.