I am attempting to attach the handle parts of head/hat/face accessories to a non-humanoid-based character’s head. The head has been scaled up to 16 times the original size, so how would I go about scaling up the handles of the required accessories to be proportionate with the head, and apply correct placement to them within the model?
The “character” itself does not have a body, it’s just a head, so accessories which attach to other parts of the body are not necessary. I believe I can load only the accessories I need via the Players:GetCharacterAppearanceInfoAsync and InsertService:LoadAsset functions. It’s just positioning a scaled-up accessory handle to their correct position in relation to the scaled-up head which I am struggling to understand.
Do you have the correct attachments in the Head and are these positioned correctly?
This code assumes that the accessories aren’t already scaled and that the Head has correctly positioned attachments.
local function scaleAccoutrement(accoutrement, scaleVector3)
local function scaleItem(obj)
if obj:IsA("BasePart") then
local cf = obj.CFrame
obj.Size = obj.Size * scaleVector3
obj.CFrame = cf - cf.p + (cf.p * scaleVector3)
elseif obj:IsA("Attachment") then
obj.Position = obj.Position * scaleVector3
elseif obj:IsA("SpecialMesh") and obj.MeshType ~= Enum.MeshType.Head then
obj.Scale = obj.Scale * scaleVector3
obj.Offset = obj.Offset * scaleVector3
end
for _, child in pairs(obj:GetChildren()) do
scaleItem(child)
end
end
for _, child in pairs(accoutrement:GetChildren()) do
scaleItem(child)
end
end
local function buildWeld(weldName, parent, part0, part1, c0, c1)
local weld = Instance.new("Weld")
weld.Name = weldName
weld.Part0 = part0
weld.Part1 = part1
weld.C0 = c0
weld.C1 = c1
weld.Parent = parent
return weld
end
local 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
local foundAttachment = findFirstMatchingAttachment(child, name)
if foundAttachment then
return foundAttachment
end
end
end
end
-- Only works correctly with accessories that should attach to the Head
local function addAccoutrement(head, headScale, item)
item.Parent = head.Parent
scaleAccoutrement(item, headScale)
local handle = item:FindFirstChild("Handle")
if not handle then
return
end
local accoutrementAttachment = handle:FindFirstChildOfClass("Attachment")
local headAttachment = accoutrementAttachment and findFirstMatchingAttachment(head, accoutrementAttachment.Name) or nil
local attachmentCFrame = headAttachment and headAttachment.CFrame or CFrame.new(0, 0.5 * headScale.Y, 0)
local hatCFrame = accoutrementAttachment and accoutrementAttachment.CFrame or item.AttachmentPoint
-- Anchored case
handle.CFrame = head.CFrame * attachmentCFrame * hatCFrame:inverse()
-- Weld
buildWeld("AccessoryWeld", handle, handle, head, hatCFrame, attachmentCFrame)
end
local HEAD_SCALE = Vector3.new(16, 16, 16)
local headPart = game.Workspace.Character.Head
local accessory = game.Workspace.BlackDominoCrown:Clone()
addAccoutrement(headPart, HEAD_SCALE, accessory)
Something like this should work for your purposes.