To preface, I am working on a game where I need to resize quite a few parts at the same time in increments of less than one, unfortunately BasePart:Resize() does not support using increments of less than one.
So my solution was to create a module, the module works fine and allows me to resize in any direction by any amount without any issues.
Here is the code of the original module:
--!strict
local fineResize = {}
function fineResize.FineResize(part: Part, resizeVector: Enum.NormalId, resizeBy: number)
local PartPosX: number, PartPosY: number, PartPosZ: number = part.Position.X, part.Position.Y, part.Position.Z
local PartSizeX: number, PartSizeY: number, PartSizeZ: number = part.Size.X, part.Size.Y, part.Size.Z
if resizeVector == Enum.NormalId.Top then
part.Size = Vector3.new(PartSizeX, (PartSizeY + resizeBy), PartSizeZ)
part.Position = Vector3.new(PartPosX, (PartPosY + (resizeBy/2)), PartPosZ)
return true
elseif resizeVector == Enum.NormalId.Bottom then
part.Size = Vector3.new(PartSizeX, (PartSizeY + resizeBy), PartSizeZ)
part.Position = Vector3.new(PartPosX, (PartPosY - (resizeBy/2)), PartPosZ)
return true
elseif resizeVector == Enum.NormalId.Left then
part.Size = Vector3.new((PartSizeX+resizeBy), PartSizeY, PartSizeZ)
part.Position = Vector3.new((PartPosX - (resizeBy/2)), PartPosY, PartPosZ)
return true
elseif resizeVector == Enum.NormalId.Right then
part.Size = Vector3.new((PartSizeX+resizeBy), PartSizeY, PartSizeZ)
part.Position = Vector3.new((PartPosX + (resizeBy/2)), PartPosY, PartPosZ)
return true
elseif resizeVector == Enum.NormalId.Front then
part.Size = Vector3.new(PartSizeX, PartSizeY, (PartSizeZ+resizeBy))
part.Position = Vector3.new(PartPosX, PartPosY, (PartPosZ - (resizeBy/2)))
return true
elseif resizeVector == Enum.NormalId.Back then
part.Size = Vector3.new(PartSizeX, PartSizeY, (PartSizeZ+resizeBy))
part.Position = Vector3.new(PartPosX, PartPosY, (PartPosZ + (resizeBy/2)))
return true
end
return false
end
return fineResize
This worked fine! However, I felt it was a bit ugly and could run a bit faster, so I decided to use a table with functions, instead of a large amount of if statements, which looks like this:
--!strict
local fineResize = {}
local function Top(part: Part, resizeVector: Enum.NormalId, resizeBy: number)
local PartPosX: number, PartPosY: number, PartPosZ: number = part.Position.X, part.Position.Y, part.Position.Z
local PartSizeX: number, PartSizeY: number, PartSizeZ: number = part.Size.X, part.Size.Y, part.Size.Z
part.Size = Vector3.new(PartSizeX, (PartSizeY + resizeBy), PartSizeZ)
part.Position = Vector3.new(PartPosX, (PartPosY + (resizeBy/2)), PartPosZ)
return true
end
local function Bottom(part: Part, resizeVector: Enum.NormalId, resizeBy: number)
local PartPosX: number, PartPosY: number, PartPosZ: number = part.Position.X, part.Position.Y, part.Position.Z
local PartSizeX: number, PartSizeY: number, PartSizeZ: number = part.Size.X, part.Size.Y, part.Size.Z
part.Size = Vector3.new(PartSizeX, (PartSizeY + resizeBy), PartSizeZ)
part.Position = Vector3.new(PartPosX, (PartPosY - (resizeBy/2)), PartPosZ)
return true
end
local function Left(part: Part, resizeVector: Enum.NormalId, resizeBy: number)
local PartPosX: number, PartPosY: number, PartPosZ: number = part.Position.X, part.Position.Y, part.Position.Z
local PartSizeX: number, PartSizeY: number, PartSizeZ: number = part.Size.X, part.Size.Y, part.Size.Z
part.Size = Vector3.new((PartSizeX+resizeBy), PartSizeY, PartSizeZ)
part.Position = Vector3.new((PartPosX - (resizeBy/2)), PartPosY, PartPosZ)
return true
end
local function Right(part: Part, resizeVector: Enum.NormalId, resizeBy: number)
local PartPosX: number, PartPosY: number, PartPosZ: number = part.Position.X, part.Position.Y, part.Position.Z
local PartSizeX: number, PartSizeY: number, PartSizeZ: number = part.Size.X, part.Size.Y, part.Size.Z
part.Size = Vector3.new((PartSizeX+resizeBy), PartSizeY, PartSizeZ)
part.Position = Vector3.new((PartPosX + (resizeBy/2)), PartPosY, PartPosZ)
return true
end
local function Front(part: Part, resizeVector: Enum.NormalId, resizeBy: number)
local PartPosX: number, PartPosY: number, PartPosZ: number = part.Position.X, part.Position.Y, part.Position.Z
local PartSizeX: number, PartSizeY: number, PartSizeZ: number = part.Size.X, part.Size.Y, part.Size.Z
part.Size = Vector3.new(PartSizeX, PartSizeY, (PartSizeZ+resizeBy))
part.Position = Vector3.new(PartPosX, PartPosY, (PartPosZ - (resizeBy/2)))
return true
end
local function Back(part: Part, resizeVector: Enum.NormalId, resizeBy: number)
local PartPosX: number, PartPosY: number, PartPosZ: number = part.Position.X, part.Position.Y, part.Position.Z
local PartSizeX: number, PartSizeY: number, PartSizeZ: number = part.Size.X, part.Size.Y, part.Size.Z
part.Size = Vector3.new(PartSizeX, PartSizeY, (PartSizeZ+resizeBy))
part.Position = Vector3.new(PartPosX, PartPosY, (PartPosZ + (resizeBy/2)))
return true
end
local t =
{
[Enum.NormalId.Top] = Top,
[Enum.NormalId.Bottom] = Bottom,
[Enum.NormalId.Left] = Left,
[Enum.NormalId.Right] = Right,
[Enum.NormalId.Front] = Front,
[Enum.NormalId.Back] = Back
}
function fineResize.FineResize(part: Part, resizeVector: Enum.NormalId, resizeBy: number)
local func = t[resizeVector]
func(part, resizeVector, resizeBy)
return false
end
return fineResize
Now, by moving those conditional statements out into a simple table, and indexing it directly, one would expect this new code to run substantially faster, however, it is actually about 20ms slower (in a BEST case scenario, even!) on a task with a runtime of about 220ms. (The task in question is mass-resizing 20000 parts without a wait)
Now no, I do not need to resize 20000 parts at once in my usecase, however, I would still like to understand why this is slower for future reference, thanks!