Mind blown. Thanks for teaching me a new cframe method
It was on the old wiki I discovered it last week and have been trying to think of some useful applications for it that aren’t already handled by the ROBLOX engine, but you’d be the first to give me such an idea.
By the way, it works for all of the ToWorldSpace and ToObjectSpace methods, i.e. those plus the ones for points and vectors.
How do you handle welds in your models? Don’t all the welds break when rescaling the parts?
Yeah they would probably break, or otherwise just put things in the wrong position. You would have to scale the C0/C1 properties of the welds.
If you’re auto-welding, I would recommend scaling first before welding
All the parts from my model have scaled, but their positions appear to remain the same. As a result, there are gaps between all my parts (I am scaling down). I do have welds connecting some parts together since it is a moving object. Solutions would be appreciated.
I had the same issue, but I figured it out.
local function scaleModel(model, scale)
local PrimaryPart = model.PrimaryPart
local PrimaryPartCFrame = model:GetPrimaryPartCFrame()
--Destroy welds
for _,object in pairs(model:GetDescendants()) do
if object:IsA('BasePart') then
for _,object in pairs(object:GetDescendants()) do
if object:IsA('Weld') or object:IsA('ManualWeld') or object:IsA('WeldConstraint') then
pcall(function()
object.Part0.Anchored = true
object.Part1.Anchored = true
end)
object:Destroy()
end
end
end
end
--Scale BaseParts
for _,object in pairs(model:GetDescendants()) do
if object:IsA('BasePart') then
object.Size = object.Size*scale
local distance = (object.Position - PrimaryPartCFrame.p)
local rotation = (object.CFrame - object.Position)
object.CFrame = (CFrame.new(PrimaryPartCFrame.p + distance*scale) * rotation)
end
end
end
Hello guys,
I asked @KoxuVBC in a private message for a solution where the parts of the model are not anchored. He then gave me this advise:
This is my implementation, which works. I want to share it with you. Maybe even someone has a suggestion for improvement.
local function scaleModel(model, scale)
local PrimaryPart = model.PrimaryPart
local PrimaryPartCFrame = model:GetPrimaryPartCFrame()
--Destroy welds
for _,object in pairs(model:GetDescendants()) do
if object:IsA('Weld') or object:IsA('ManualWeld') or object:IsA('WeldConstraint') then
object:Destroy()
end
end
for _,object in pairs(model:GetDescendants()) do
if object:IsA('BasePart') then
for _,object2 in pairs(model:GetDescendants()) do
if object2:IsA('BasePart') then
if object ~= object2 then
local constraint = Instance.new("WeldConstraint")
constraint.Part0 = object
constraint.Part1 = object2
constraint.Parent = object
end
end
end
end
end
--Scale BaseParts
for _,object in pairs(model:GetDescendants()) do
if object:IsA('BasePart') then
object.Size = object.Size*scale
local distance = (object.Position - PrimaryPartCFrame.p)
local rotation = (object.CFrame - object.Position)
object.CFrame = (CFrame.new(PrimaryPartCFrame.p + distance*scale) * rotation)
end
end
end
Greetings!
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.
Cool, yep, I knew about that, but I need to resize Models at runtime with script.
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…
How can I adjust this to work “down-up”?
Like if the scale would be adjusted with the scale tool in studio
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.
You could use multiple threads to speed it up
For some reason I used this code and I have an issue where a union welded onto a model would be in the wrong orientation when using this function
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.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.