Size model without distorting it?

Hello! I am sizing a model using a loop that just adds to every child of the model every time a part is clicked:

local balloon = script.Parent.Parent.Parent.Parent.Parent.RedBalloon

script.Parent.MouseClick:Connect(function(plr)
	for _,v in pairs(balloon:GetChildren()) do
		if v:IsA("BasePart") then
			v.Size = Vector3.new(v.Size.X + 10,v.Size.Y + 10,v.Size.Z + 10)
		end
	end
end)

It works perfectly except for the fact that the balloon is very distorted because there is three parts, a string and a string around the end of the balloon, the problem is that they don’t stay connected to the balloon but still size up:
image
What it should look like:


Could anyone help? Thank you!

3 Likes

If you want to do this the way you are currently doing this you would need to also change the position of the Instances which could be quite complicated. So instead to make this easier you can try using TweenService to do this. You can read about this here: TweenService | Roblox Creator Documentation or you can watch about it here: Advanced Roblox Scripting Tutorial #10 - TweenService / Tween (Beginner to Pro 2019) - YouTube

2 Likes

Tried this and it is better, but still has the problem of the other parts not sizing up with it:

local balloon = script.Parent.Parent.Parent.Parent.Parent.RedBalloon.PrimaryPart
local tweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)
local tween = tweenService:Create(balloon, tweenInfo, {Size = Vector3.new(5,5,5)})

script.Parent.MouseClick:Connect(function(plr)
	tween:Play()
end)

Thanks for the help

1 Like

You would need to also pass the position parameter into the tween. You will need to use the CFrame toWorldSpace function for this unless the balloon is going to stay in the same place in the game, in this case you can just size it up in studio and copy the position of all the components of the balloon.(You also need to make a tween for all the parts in the model)

Okay, it is going to stay in one place so I will try what you said.

Ok, when you do this you will need to make a tween for all the parts in the model if they are going to change size/position.

Okay I tried this and it didn’t give an error it did simply nothing, here is the new code:

local balloon = script.Parent.Parent.Parent.Parent.Parent.RedBalloon
local tweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)

script.Parent.MouseClick:Connect(function(plr)
	local tween1 = tweenService:Create(balloon.Part1, tweenInfo, {Size = Vector3.new(0.097, 1.096, 0.138)})
	local tween2 = tweenService:Create(balloon.Part2, tweenInfo, {Size = Vector3.new(2.239, 3.273, 2.239)})
	local tween3 = tweenService:Create(balloon.Part3, tweenInfo, {Size = Vector3.new(0.484, 0.117, 0.419)})
	tween1:Play()
	tween2:Play()
	tween3:Play()
end)

Is CanCollide on? if so it needs to probably be off and you also need to put a Position value in the tweenInfo. If you dont want anything to collide with it while it is changing size you can use physics service I believe.

CanCollide is off on all three parts, I also don’t really know how I put the position size in the tween info but would that fix the problem of it not doing anything?

Well I notice you changed the size to 5,5,5 earlier now it is way smaller, is it the same size as it currently is so you dont se a difference? Also to change the position you just have to add a property after size named position. ex. {Size = Vector3.new(0.484, 0.117, 0.419), Position = Vector3.new(x,y,z)}

1 Like

Ah yes… My mistake haha, thank you so much for helping it works perfectly now!

1 Like

You would want to use a formula to find the difference between the first size and the second size and then size it proportionately. TweenService isn’t really relevant in our case unless you want to create a smooth size effect. It’s mostly math and vector knowledge.

local initSize = Vector3.new(2,5,1.5) -- this would be any Vector3
local currentSize = Vector3.new(1,11.2,1) -- let's say 4.5 is the goal size but we only have the Y axis, this would be the new size

local offset = currentSize.Y / initSize.Y -- this will be how much bigger or smaller one of the axes will be
local x = initSize.X * offset
local y = currentSize.Y
local z = initSize.Z * offset

local scaledSize = Vector3.new(x,y,z)
workspace.ScaledPart.Size = scaledSize

This should scale up the part proportionately.

Now that’s only one part, what if we have more than one part? For the second part, we have to find the relative position from one part to the other. Thankfully, Roblox allows us to do this easily with CFrames.

To make it easier, let’s create a function to organize our code into functions.

local function getOffsetSize(initVector, offset) -- requires the part's size and the offset (new) size
	local x = initVector.X * offset
	local y = initVector.Y * offset
	local z = initVector.Z * offset

	return Vector3.new(x,y,z)
end

local function getOffset(initYAxis, goal) -- requires our initial Y axis and our goal axis
	return goal / initYAxis
end

local function getOffsetPosition(primaryPartCFrame, part, offset) -- requires the models' primary part CFrame and our target part's cframe as well as the offset  from the above function
	local relativeVector = primaryPartCFrame:PointToObjectSpace(part.Position)
	print(relativeVector)
	local x = relativeVector.X * offset
	local y = relativeVector.Y * offset
	local z = relativeVector.Z * offset
	local relativeVector = Vector3.new(x,y,z)
	return primaryPartCFrame:PointToWorldSpace(relativeVector)
end

Finally, let’s test it out:

local scaleModelExample = workspace.ScaleModelExample

local initSize = scaleModelExample.PrimaryPart.Size
local goalSizeY = 11.2
local offset = getOffset(initSize.Y, goalSizeY)

local scaledSize = getOffsetSize(initSize, offset)

scaleModelExample.PrimaryPart.Size = scaledSize

for i,v in pairs(scaleModelExample:GetChildren()) do
	if v ~= scaleModelExample.PrimaryPart and v:IsA('BasePart') then -- just avoids an unnecessary calculation
		v.Size = getOffsetSize(v.Size, offset)
		v.Position = getOffsetPosition(scaleModelExample.PrimaryPart.CFrame, v, offset) -- recycle the offset variable returned from getOffset
	end
end

3 Likes