The problem is that your code welds the “armor” to the character based on where they are in relation to eachother at the time of welding. You might be better off welding each armor piece to the correlated body part with C0 and C1 set to CFrame.new(0,0,0).
C0 and C1 are properties of a weld.
Both C0 and C1 combine to determine the spacial relation between the Part0 and Part1. If you set both C0 and C1 to be blank CFrames, then Part0 and Part1 will be welded directly to the center of eachother.
The parts are already welded to the center of eachother, which isn’t what I want. In the model, the Part1 has an offset from the center of the part that I would like to preserve in the weld.
Did you try to place it into the person itself or readd it. There maybe a bug or it was placed in the wrong part/model so try to check that let me know if that works or not.
If you have a model that the armor is aligned to, you can generate the offset by setting the C0 or the C1 to the relative CFrame of the armor template to the model that it is aligned to.
Your original CFrame code seems to do this, but I am not sure if it uses a properly aligned template.
I might be able to write you up some working code if you can share more of your original code. Please format code by using ``` before and after the code.
local currentArmor = char:FindFirstChild("Armor"):GetChildren()
if #currentArmor > 0 then
-- // need to unequip
for i = 1, #currentArmor do
local selectedPart = currentArmor[i]
selectedPart:Destroy()
equippedArmors[player] = nil
end
end
local newArmor = Armors:FindFirstChild(armor):Clone()
local children = newArmor:GetChildren()
for i = 1, #children do
local selectedArmorPiece = children[i]
local weld = Instance.new("Weld")
local playerBodyPart = char:FindFirstChild(selectedArmorPiece.Name)
weld.C0 = CFrame.new(0, 0, 0)
weld.C1 = selectedArmorPiece.CFrame
weld.Part0 = playerBodyPart
weld.Part1 = selectedArmorPiece
weld.Parent = selectedArmorPiece
selectedArmorPiece.Parent = char.Armor
end
You will need to make a new folder of characters that the armors are aligned to. If you instead want to, you could align all of the armors to a single character model. If that is the case, just set armorAlignmentModel to that model.
local replicatedStorage = game:GetService('ReplicatedStorage')
local equippedArmors = {}
local Armors = replicatedStorage:WaitForChild('Armors')
local armorAlignmentModels = replicatedStorage:WaitForChild('ArmorsAlignment')
function equipArmor(player, char, armorName)
local currentArmor = char:FindFirstChild("Armor"):GetChildren()
if #currentArmor > 0 then
-- // need to unequip
for i = 1, #currentArmor do
local selectedPart = currentArmor[i]
selectedPart:Destroy()
equippedArmors[player] = nil
end
end
local newArmor = Armors:FindFirstChild(armorName):Clone()
local alignmentModel = armorAlignmentModels:FindFirstChild(armorName)
local children = newArmor:GetChildren()
for i = 1, #children do
local selectedArmorPiece = children[i]
local weld = Instance.new("Weld")
local playerBodyPart = char:FindFirstChild(selectedArmorPiece.Name)
local alignmentBodyPart = alignmentModel:FindFirstChild(selectedArmorPiece.Name)
weld.C0 = alignmentBodyPart.CFrame:ToObjectSpace(selectedArmorPiece.CFrame)
weld.Part0 = playerBodyPart
weld.Part1 = selectedArmorPiece
weld.Parent = selectedArmorPiece
selectedArmorPiece.Parent = char.Armor
end
end
You need a model that the armor is currently aligned to so that you know the offsets to weld it to the player. I assume that the armor pieces are not already aligned perfectly on the actual player, so instead you have a dummy model that the armors are already aligned to, and weld them to the player with the same alignment they have to the dummy.