Scaling models with Rotation/Orientation

Hello, I’ve been needing to scale character models for quite a while now and I just can’t seem to figure this out on my own, I know how to scale the model and it works if there is no rotation but as soon as I add some some rotation it goes completely bonkers

No rotation growing

Growing with some rotation

my goal is for the script to account for both the orientation of the PrimaryPart and the other Parts inside of the model

Script
local Worm = workspace:WaitForChild("Worm")


function Scale(Model, Scale) -- loops through model and scales
	
	local Primary = Model.PrimaryPart
	local PrimaryCFrame = Primary.CFrame
	
	for i, Part in pairs(Model:GetChildren()) do
		if Part:IsA("BasePart") then
			
			Part.Size = (Part.Size * Scale) -- scales the part
			if Part ~= Primary then
			Part.CFrame = (PrimaryCFrame + (PrimaryCFrame:inverse() * Part.Position * Scale)) -- if the part isnt the primary part scale the position
			end
			
		end
	end
	
end



while true do
wait(.3)
Scale(Worm, 1.02)
end

I researched quite heavily on this but I couldn’t find anything that scales with orientation

most of the code I got right now is from Is this the best way to scale a model? which is useful but only really works with stationary models with no rotation

I don’t know if this is simple and it’s just going over my head any help would be amazing

I would do something like this.

function Scale(Model, Scale) -- loops through model and scales
	
	local Primary = Model.PrimaryPart
	local PrimaryCFrame = Primary.CFrame
	
	for i, Part in pairs(Model:GetChildren()) do
		if Part:IsA("BasePart") then
			
			Part.Size = (Part.Size * Scale) -- scales the part
			if Part ~= Primary then
			Part.CFrame = PrimaryCFrame:ToWoldSpace(PrimaryCFrame:ToObjectSpace(Part.CFrame)*Scale)
 -- if the part isnt the primary part scale the position
			end
			
		end
	end
	
end

Note that I really suck at math with CFrames, and I’m on mobile so I couldn’t test it.

image

Sorry, I really over complicated it. To get the scaled position you would find the Vector (Part.Position-PrimaryPartPosition) then multiply that by scale. Then add the primary parts position back. In code it would be like this

function Scale(Model, Scale) -- loops through model and scales
	
	local Primary = Model.PrimaryPart
	local PrimaryCFrame = Primary.CFrame
	
	for i, Part in pairs(Model:GetChildren()) do
		if Part:IsA("BasePart") then
			
			Part.Size = (Part.Size * Scale) -- scales the part
			if Part ~= Primary then
			Part.Position = PrimaryCFrame.Position + (Part.Position-PrimaryCFrame.Position)* Scale
 -- if the part isnt the primary part scale the position
			end
			
		end
	end
	
end
1 Like

Although positions don’t include rotation data this would still work. This is because a vector is both a magnitude and a direction. So when you calculate target-pos it tells you which direction it is and how far away. If you multiply it by a number it only changes the distance and not the direction.

Ah I see I misunderstood it, sorry

I would recommend anchoring all the parts before resizing or you’ll get very unpleasant results

Code
local function ScaleModel_Func(Model, Scale)
	local BaseParts = {}
	local PrimaryPart = Model.PrimaryPart
	local PrimaryPartCFrame = PrimaryPart.CFrame
	for _,v in pairs(Model:GetDescendants()) do
		if v:IsA('BasePart') then
			BaseParts[v] = v.Anchored
			v.Anchored = true
			v.Size = (v.Size * Scale)
			if v ~= PrimaryPart then
				v.Position = PrimaryPartCFrame.Position + (v.Position-PrimaryPartCFrame.Position)* Scale
			end
		end
	end
	for i,v in pairs(BaseParts) do
		i.Anchored = v
	end
end

I also ran into a weird issue, not sure how to fix or why it’s occurring

After resizing multiple times it looks fine on the Server but looks horrible on the Client.

repro.rbxl (33.4 KB)



1 Like

I actually am having this same issue (my character sometimes looks fine on the server but looks bad on the client)