Sorry, I meant to post this code a few days ago.
function findFirstMatchingAttachment(model, name)
for _, child in pairs(model:GetChildren()) do
if child:IsA("Attachment") and child.Name == name then
return child
elseif not child:IsA("Accoutrement") and not child:IsA("Tool") then -- don't look in hats or tools in the character
local foundAttachment = findFirstMatchingAttachment(child, name)
if foundAttachment then
return foundAttachment
end
end
end
end
local function getOriginalScale(handle)
local origScaleValue = handle:FindFirstChild("OriginalScale")
if not origScaleValue then
origScaleValue = Instance.new("Vector3Value")
origScaleValue.Name = "OriginalScale"
origScaleValue.Value = handle.Size
origScaleValue.Parent = handle
end
return origScaleValue.Value
end
local function findHandleMesh(handle)
for _, obj in pairs(handle:GetChildren()) do
if obj:IsA("DataModelMesh") then
return obj
end
end
end
local function getAccoutrementWeld(attachmentPart, handle)
local accessoryWeld = handle:FindFirstChild("AccessoryWeld")
if accessoryWeld then
return accessoryWeld, accessoryWeld.Parent
end
-- Legacy case
for _, obj in pairs(attachmentPart:GetChildren()) do
if obj:IsA("Weld") then
if obj.Part0 == handle or obj.Part1 == handle then
return obj, obj.Parent
end
end
end
return nil
end
local function rescaleAccessories(character, bodyScaleVector, headScale)
local humanoid = character:FindFirstChildOfClass("Humanoid")
for _, obj in pairs(character:GetChildren()) do
if obj:IsA("Accoutrement") then
local handle = obj:FindFirstChild("Handle")
if handle then
local originalSize = getOriginalScale(handle)
local currentScaleVector = handle.Size/originalSize
local desiredScaleVector = bodyScaleVector
local accoutrementAttachment = handle:FindFirstChildOfClass("Attachment")
local characterAttachment = accoutrementAttachment and findFirstMatchingAttachment(character, accoutrementAttachment.Name) or nil
local attachmentPart = characterAttachment and characterAttachment.Parent or character:FindFirstChild("Head")
if attachmentPart then
if attachmentPart.Name == "Head" then
desiredScaleVector = Vector3.new(headScale, headScale, headScale)
end
local modifyVector = desiredScaleVector/currentScaleVector
local accoutrementWeld, oldParent = getAccoutrementWeld(attachmentPart, handle)
accoutrementWeld = accoutrementWeld and accoutrementWeld:Clone() or nil -- Weld will be broken when scaling, create a new one
handle.Size = handle.Size * modifyVector
local handleMesh = findHandleMesh(handle)
if handleMesh then
handleMesh.Scale = handleMesh.Scale * modifyVector
end
if accoutrementAttachment then
-- Accessory case is easier
accoutrementAttachment.Position = accoutrementAttachment.Position * modifyVector
end
-- Legacy hat logic case
local x, y, z, R00, R01, R02, R10, R11, R12, R20, R21, R22 = obj.AttachmentPoint:components()
obj.AttachmentPoint = CFrame.new(x*modifyVector.x, y*modifyVector.y, z*modifyVector.z, R00, R01, R02, R10, R11, R12, R20, R21, R22)
local attachmentCFrame = characterAttachment and characterAttachment.CFrame or CFrame.new(0, 0.5*headScale, 0)
local hatCFrame = accoutrementAttachment and accoutrementAttachment.CFrame or obj.AttachmentPoint
if accoutrementWeld then
accoutrementWeld.Parent = oldParent
if oldParent == handle then
accoutrementWeld.C0 = hatCFrame
accoutrementWeld.C1 = attachmentCFrame
else
accoutrementWeld.C0 = attachmentCFrame
accoutrementWeld.C1 = hatCFrame
end
end
end
end
end
end
end
-- Used like this, call after re-scaling the character with the new scale values.
rescaleAccessories(game.Workspace.Player1, Vector3.new(0.75, 2, 1), 1)