How to resize a complex model via script without using any plugin

Hi Folks,

I’m coding in Roblox Studio since a while but I’m still looking for the simplest and clean way for resizing a model especially the complex ones, like a plane or a car that you can find in the Toolbox, without using any plugin.

I read a lot of posts on this forum and watched videos on Youtube and seems that you need to resize every single part of the model for obtaining the final result: how can be possible that, one of the main features that a user wants to implement via coding (i.e. the resizing of a model) must be so “complicated”? And how can this way impact on the performances?

For example, how would you write the code for resizing a complex model like the one with Asset ID 663620832? (it is an Embraer Phenom 100)

1 Like

Performance impact depends on how many parts your model has.
In order to resize a model, you have to set something as the primary part of your model. You then have to go down every part in the model, change the size by whatever multiplier you want, and also move it relative to the primary part.

Effectively, if my model is compromised of 2 parts, the primary part being at 0, 10, 0 and the other part being at 0, 10, 1, in order to rescale it by 1.5 I’d have to multiply the position by 1.5 relative to the primary part, giving me 0, 10, 1.5.
This means substracting the position of the part with the position of the primary part, multiplying it by the desired value, then adding the position of the primary part back in.

local multiplier = 1.5
local primaryPart = model.PrimaryPart
for _, part in ipairs(model:GetDescendants()) do
     if part:IsA("BasePart") then
          local relativePosition = part.Position - primaryPart.Position
          local rescaledPosition = relativePosition * multiplier
          part.Position = rescaledPosition + primaryPart.Position
          part.Size *= multiplier
     end
end

Of course, you’ll also need to apply the same logic to welds, constraints, attachments, etc. otherwise they will still be based on the original size.

4 Likes

Thanks for your reply. The problem is just that: you need to go to every single part (checking what is a BasePart and what not) and make every single computation for resizing a model (creating a primary part if the model lacks of it) and moreover you have to consider even the welding parts. I think that it is a very strong lacuna the fact that in a tool like Roblox there is not an integrated method for the Model class for making interpolations in clean and simple manner since it is probably one of the main things that a programmer wants to do in a game.

The engine probably does an extremely similar process as what I’ve posted when you rescale things in studio. A model isn’t a single mesh, it’s a big collection of parts. It’s impossible to apply a huge modification to all the parts without going down every part and actually applying the modification to them.

If you goal is to optimize these kinds of computations, use meshes instead of models. A mesh is treated as a single part rather than a collection of parts, and as such you only need to rescale a single part instead of all of the model’s descendants.

1 Like

Indeed, meshes are, at the moment, the best things for resizing and stuff like this but, using them istead of models, you can loose a high level of details.

Either way you’re going to have to pick between using meshes or models. There’s no perfect solution to this issue, you will have to compromise one way or another.

You are correct direct API are more efficient because they are often integrated with the underlying C++ code base making them more efficient since LUA code is funneled through a the default C++ pipeline.
This function is fine until it times out due to a model with too many descendants. Depending on the application you could add a task.wait() to the function. To make it not ever timeout. Or if your index of parts is simple enough to use Getchildren() to do so instead. If you want it to fire instantly you could use spawn(function() local part=part end) to encompass the conditionals within the for _, do statement.

I’m going to be using this function for my own purposes so here is my draft code I wrote here. It should just work but I haven’t tested it.
function ScaleModel(model,multiplier)
local primaryPart
primaryPart = model.PrimaryPart
for _, part in ipairs(model:GetDescendants()) do
if part:IsA(“BasePart”) then
if model.PrimaryPart==nil then
model.PrimaryPart=part
primaryPart=model.PrimaryPart
end
local relativePosition = part.Position - primaryPart.Position
local rescaledPosition = relativePosition * multiplier
part.Position = rescaledPosition + primaryPart.Position
part.Size=part.Size*multiplier
end
if part:IsA(“SpecialMesh”) then
part.Scale=part.Scale * multiplier
part.Offset=part.Offset * multiplier
end
end
end

local Model=script.Parent
local Scale=1.5
ScaleModel(Model,Scale)

pretty sure u can use the :scaleto function

2 Likes

just use Model:ScaleTo(desired size)