For some reason, OP’s code doesn’t work for a model I was trying to scale. If you get weird scaling behavior in the future when trying to use the code, this code works for me:
function scaleModel(model, scale)
local origin = model.PrimaryPart.Position
for _, part in ipairs(model:GetDescendants()) do
if part:IsA("BasePart") then
local pos = part.Position
local rotCf = part.CFrame - pos
local fromOriginDir = pos - origin
part.Size *= Vector3.new(scale, scale, scale)
part.CFrame = rotCf + origin + fromOriginDir*scale
end
end
end
I made @rbxts package for scale-model because this could be a little tricky. It needs to scale bunch of different kinds of sub-objects. For example, my package can scale Fire, Attachments, and even a NumberSequence inside of a ParticleEmitter.
You can install it to roblox-ts solution with npm i @rbxts/scale-model
Sourcecode in Typescript could be found on my Github
I made a roblox-ts Playground which will show the sourcecode compiled to Lua, however it’s not very human-friendly.
I’m using model:GetBoundingBox() as the primaryCf. I run the function the first time to scale it down, and then tween it back to its original size using the same function.
And for some reason the model always ends up rotated 180 degrees, is there a way to fix this? I’m not really experienced in Cframes so I would really appreciate it if someone could fix it…
Sorry for the bump, but I revised the functions mentioned here to also account for welded models. In this thread there are functions that delete the welds altogether, but that is not practical if those welds are needed. I simply adjust the offset of the joints’ C0 and C1 values based on the scale variable.
Thought this may be useful for others, so here it is:
function scaleModelWithJoints(model, scale)
local origin = model.PrimaryPart.Position
for _, obj in ipairs(model:GetDescendants()) do
if obj:IsA("BasePart") then
obj.Size = obj.Size*scale
local distance = (obj.Position - model:GetPrimaryPartCFrame().p)
local rotation = (obj.CFrame - obj.Position)
obj.CFrame = (CFrame.new(model:GetPrimaryPartCFrame().p + distance*scale) * rotation)
elseif obj:IsA("JointInstance") then
local c0NewPos = obj.C0.p*scale
local c0RotX, c0RotY, c0RotZ = obj.C0:ToEulerAnglesXYZ()
local c1NewPos = obj.C1.p*scale
local c1RotX, c1RotY, c1RotZ = obj.C1:ToEulerAnglesXYZ()
obj.C0 = CFrame.new(c0NewPos)*CFrame.Angles(c0RotX, c0RotY, c0RotZ)
obj.C1 = CFrame.new(c1NewPos)*CFrame.Angles(c1RotX, c1RotY, c1RotZ)
end
end
end
This function also allows the function to be scaled to a larger size which is what some of the functions listed in this thread were unable to do.
Do you have any plans to add ‘bones’ to the scaling? I am trying to scale a mesh with bones at runtime, and though it scales perfect, with the studio scaling tool, when I try to do it myself in code, I can’t get the bones to scale correctly.
As of March 2023, we now have the Model.Scale property, which can be set within Roblox Studio. We also have the Model:ScaleTo(scale) and Model:GetScale() methods, which can be used during runtime (and in Studio).
A lot of people reference this post, so I wanted to make one final post here about the official way to scale a model.