Welds not behaving as they should

I want to do some character part hot swapping at runtime and at some point last year I arrived at the conclusion that using welds is the best way to achieve this. I vividly remember the snippet below working when I first wrote it, however coming back to visit the exact same place where it once worked, it no longer does. And I haven’t a clue why. I’ve tried setting the target parts’ .Massless property to on, but that doesn’t seem to achieve anything. I’d appreciate any help.

local function nudize(character)
	for _, child in pairs (character:GetChildren()) do
		if child:IsA("Clothing") or child:IsA("Accessory") then 
			child:Destroy()
		end
	end
end

local function weldArmour(armourPart, character)
	local characterPartName = character:FindFirstChild(armourPart.Name)
	if characterPartName then 
		characterPartName.Transparency = 1 -- makes all character parts invisible so armour is visible
		
		local newWeld = Instance.new("Weld");
		newWeld.Part0 = characterPartName
		newWeld.Part1 = armourPart
		newWeld.C0 = CFrame.new()
		newWeld.Parent = characterPartName
	end
end

function giveArmour(player)
	local character = player.Character --or player.CharacterAdded:Wait() 
	repeat wait() until player.HasAppearanceLoaded -- waits for player to succesfully load in and load apperance
	nudize(character)
	local armourClone = armour:Clone()
	for _, child in pairs(armourClone:GetChildren()) do
		if child:IsA("BasePart") then -- checks for unions/parts/meshparts
			child.Anchored = false
			child.CanCollide = false
			weldArmour(child, character)
		end
	end
end

players.PlayerAdded:Connect(function(player)
	giveArmour(player)
end)

This is what happens if I run this code with a standard R6 block rig from ReplicatedStorage:
Image. Ignore the accessory persistence. Studio seems to be playing Schrodinger’s Function with me where nudize only gets executed whenever it feels like it.
It should be noted this behaviour was not exhibited when the R6 block rig was parented to workspace. When that was the case my character would seem to have been welded completely to the block rig, and was unable to move. However I seem to not be able to reproduce this anymore. Lots of fishy stuff.

As it turns out, both the thing being welded and the thing being welded to need to share the same parent. Not that the wiki page for welds says anything like that.
So the solution to my problem is

...
		if child:IsA("BasePart") then 
			child.Anchored = false
			child.CanCollide = false
            child.Parent = character -- this line here
			weldArmour(child, character)
		end
...

Edit: the reason the snippet worked was because originally I was parenting the instance, but for some reason I had removed it today and I spent more time than I should’ve trying to figure out what the problem was.

1 Like