This can be used for arbitrarily shaped models as well. It also works fine with a single part. You can simply call GetBoundingBox({part}) if you don’t want to edit the code.
Sorry for 4 year bump, but figured this might be helpful to someone.
The following code functions exactly the same as the solution in this thread but I cleaned it up to match the exact needs for just a singular Part (and I also replaced any deprecated functions).
This function does for a Part exactly what GetExtentsSize does for a Model (but with the added benefit of being able to specify the orientation of the bounding box).
-- Original function by XAXA, original optimized by Pyseph--
function GetPartExtentsSize(part: BasePart, orientation: CFrame?): (Vector3)
orientation = orientation or CFrame.identity
local partCFrame: CFrame = part.CFrame
partCFrame = orientation:ToObjectSpace(partCFrame)
local size: Vector3 = part.Size
local sx: number, sy: number, sz: number = size.X, size.Y, size.Z
local x: number, y: number, z: number,
R00: number, R01: number, R02: number,
R10: number, R11: number, R12: number,
R20: number, R21: number, R22: number = partCFrame:GetComponents()
local wsx: number = 0.5 * (math.abs(R00) * sx + math.abs(R01) * sy + math.abs(R02) * sz)
local wsy: number = 0.5 * (math.abs(R10) * sx + math.abs(R11) * sy + math.abs(R12) * sz)
local wsz: number = 0.5 * (math.abs(R20) * sx + math.abs(R21) * sy + math.abs(R22) * sz)
return Vector3.new(x + wsx, y + wsy, z + wsz) - Vector3.new(x - wsx, y - wsy, z - wsz)
end