Model Rescaler module

I made a quick n easy model rescale module.

Require the module, and call module.RescaleModel(model, scale).
Be sure to set the model’s primarypart.

Roblox module link:

Source (Github):


  • BulkMove and batched operations for maximal efficiency (credits: Is this the best way to scale a model? - #10 by suremark for the trick). Note: I haven’t actually done any benchmarks, but feel free to post results if you are interested.
  • Full support for rotated models
  • Support for rigs

Possible features (pull requests welcome!):

  • Object oriented mover, to reduce calls to GetDescendants, and allow for rescaling based on initial model state.
  • Plugin form


  • 8/13: Added support for Motor6D rigs

This is great!! Will this support rigged models soon??

Haven’t tested this with rigged models - what breaks when you try rescaling it?

The Motor6D’s breaks when you rescale it.

1 Like

Would you be able to send me a rig to test with?

Here you go!
R15.rbxm (11.4 KB)

ok, new version is up - now supports rig scaling!

1 Like

I was planning on using this module to rescale 3d meshpart clothing for r15 characters, but it rescales on all axis. It won’t rescale on just one axis.

Hey, it doesn’t put the motors at the right position.

not scaled:


1 Like

Here’s the maintained version of the module


local function multiplyComponents(cframe: CFrame, multiplier: number): CFrame
	local components = {}
	for index, value in ipairs(table.pack(cframe:GetComponents())) do
		table.insert(components, index, value * multiplier)

return function(model: Model, scale: number)
	assert(typeof(model) == "Instance" and model:IsA("Model") and model.PrimaryPart, "Argument 1: You must pass a model with primary part set to rescale!")
	assert(type(scale) == "number", "Argument 2: scale must be a number!")
	local parts: {BasePart}, positions: {Vector3}, sizes: {Vector3} = {}, {}, {}
	local savedJointInstance: {[JointInstance]: {[string]: any}} = {}
	local descendants: {Instance} = model:GetDescendants()
	local primaryPart: BasePart = model.PrimaryPart
	local partToUnanchor: {BasePart} = {}
	for _, descendant in ipairs(descendants) do
		if descendant:IsA("BasePart") then
			table.insert(parts, descendant)
			table.insert(positions, descendant.Position)
			table.insert(sizes, descendant.Size)
			if not descendant.Anchored then
				table.insert(partToUnanchor, descendant)
				descendant.Anchored = true
		elseif descendant:IsA("JointInstance") then
			savedJointInstance[descendant] = {
				C0 = descendant.C0,
				C1 = descendant.C1,
				Enabled = descendant.Enabled,
				Part0 = descendant.Part0,
				Part1 = descendant.Part1
	local objectPositions = table.pack(primaryPart.CFrame:PointToObjectSpace(table.unpack(positions)))
	local scaleMatrix =, 0, 0, scale, 0, 0, 0, scale, 0, 0, 0, scale)
	local primaryCFrame = primaryPart.CFrame * scaleMatrix
	local newPoints = table.pack(primaryCFrame:PointToWorldSpace(table.unpack(objectPositions)))
	local newSizes = table.pack(scaleMatrix:PointToWorldSpace(table.unpack(sizes)))
	local newCFrames: {CFrame} = {}
	for index, part in ipairs(parts) do
		if newSizes[index] then
			part.Size = newSizes[index]
		if newPoints[index] then
			table.insert(newCFrames, index, part.CFrame - part.CFrame.Position + newPoints[index])
	for jointInstance, properties in pairs(savedJointInstance) do
		for propertyName, propertyValue in pairs(properties) do
			if propertyName == "C0" or propertyName == "C1" then
				(jointInstance :: any)[propertyName] = multiplyComponents(propertyValue, scale)
				(jointInstance :: any)[propertyName] = propertyValue
	workspace:BulkMoveTo(parts, newCFrames)
	for _, part in ipairs(partToUnanchor) do
		part.Anchored = false

An example script

local RescaleModel = require(script:WaitForChild("RescaleModel"))

RescaleModel(script.Parent, 2)

Sorry for necrobumping

Roblox has a new, built-in Model:ScaleTo function, if anyone is thinking of using a custom module such as the one in this post:

1 Like