Absolute size of a part

What’s the easiest way to get the absolute size of a part?

I’ve tried Part.CFrame.Rotation * Part.Size and it works in some circumstances but not in others.
I even tried Model:GetExtentsSize() and that does not always work too.

Do you mean volume or area?

Absolute Size itself is already available per-part as a Vector3 called “Size”.
BasePart - Size Property - ROBLOX Creator Documentation

Main reason I’m confused is that Absolute Size can refer to several things in this context. If you want the bounds based on a model’s rotation, it’d be difficult and you might have to use a trick with Resetting a model’s pivot before using the method as that resets the pivot data to have a rotation of 0. This only works if there is no PrimaryPart or if you use the primary part alone iirc.

Well, I was wanting to get the size of a randomly rotated part falling through the sky so I could stop it right before it hits the ground. I thought there would be an easy way to do this with roblox’s built-in functions or properties but I guess I’m wrong

If a part is rotating it doesn’t mean it’s size is changing

1 Like

So essentially you are looking for the lowest point on a part, yes?

You can get each corner of a box as CFrame offsets, and then constantly check to see if the lowest Y position from the 8 corners is on the ground, and once its about to hit, simply anchor it.

Is this correct?

Yeah. Well, Ideally I could get the size in x, y, and z. But yeah that’s essentially what I want.

Well the problem is that if the part is spinning, then the offset from the ground will be different as it rotates. Will it be actively spinning or is it a static rotation as it falls?

I’m talking about relative to the world. If you change the rotation of an object, it visually looks like it’s a different size. I know this shouldn’t be too hard to find, I’m just having a hard time.

It’ll be static so you don’t need to repeatedly check. I thought Part.CFrame.Rotation * Part.Size would work to get the size relative to the world but It doesn’t seem to always work.

Are you talking about something like this?

2 Likes

Thats much easier to find out then; I was thinking it was spinning.

local function getBlockOffsets(part) -- returns a list of cframe offsets from the center of the part to each corner --
	local offsets = {}
	for i = -1,1,2 do
		for j = -1,1,2 do
			for k = -1,1,2 do
				offsets[#offsets+1] = CFrame.new(part.Size.X*.5*i, part.Size.Y*.5*j, part.Size.Z*.5*k)
			end
		end
	end
	return offsets
end

This function will return a list of 8 offsets to each corner of a part, and once you do that you can just sort by the lowest point like this:

table.sort(offsets, function(A,B)
	local cf_A = copy.CFrame * A
	local cf_B = copy.CFrame * B
	return cf_A.Y < cf_B.Y
end)

The lowest offset will be at offsets[1], and you can get the world position by:
`(part.CFrame * offset[1]).Position’

If you put your part into a model you can use GetBoundingBox which will get you results like @lmaomano12345’s post

Update; messed around in studio and made this:
lowestpointonblock
-and after some refining…
lowestpointonblock2

Here is the code I used to make it, assuming the script is inside a part:

Code

local RN = game:GetService("RunService")
local DB = game:GetService("Debris")

local block = script.Parent

local function createBlock() -- this is just to create a part, you can ignore this --
	local copy = block:Clone()
	copy:ClearAllChildren() -- removes script ;)
	copy.Size = Vector3.new(math.random(2,4), math.random(1,2), math.random(3,4))*10
	copy.CFrame = block.CFrame * CFrame.Angles((math.random()-.5)*math.pi,(math.random()-.5)*math.pi,(math.random()-.5)*math.pi) + Vector3.new(0,100,50)
	copy.AssemblyAngularVelocity = Vector3.new(math.random()-.5,math.random()-.5,math.random()-.5)*100 -- random spin --
	copy.Parent = workspace
	return copy
end

local function getBlockOffsets(part) -- returns a list of cframe offsets from the center of the part to each corner --
	local offsets = {}
	for i = -1,1,2 do
		for j = -1,1,2 do
			for k = -1,1,2 do
				offsets[#offsets+1] = CFrame.new(part.Size.X*.5*i, part.Size.Y*.5*j, part.Size.Z*.5*k)
			end
		end
	end
	return offsets
end

local part = Instance.new("Part")
part.Anchored = true
part.CanCollide = false
part.Size = Vector3.new(2,2,2)
part.Material = "Neon"
part.Parent = workspace

while true do
	task.spawn(function()
		local copy = createBlock()
		local offsets = getBlockOffsets(copy)
		local connection
		connection = RN.Heartbeat:Connect(function()
			table.sort(offsets, function(A,B)
				local cf_A = copy.CFrame * A
				local cf_B = copy.CFrame * B
				return cf_A.Y < cf_B.Y
			end)
			local dest = copy.CFrame * offsets[1]
			part.CFrame = dest
			if dest.Y < .1 and connection then
				connection:Disconnect()
				connection = nil
				copy.Anchored = true
				DB:AddItem(copy, 3)
			end
		end)
	end)
	task.wait(7)
end

Its not perfect but you can tweak it as you see fit.

Yeah, is GetBoundingBox the only easy way to do it?

yeah, I am assuming it is. credits to @gertkeno though for the answer.

It’s weird because GetBoundingBox and GetExtentsSize don’t even return accurate results half of the time. I’m so confused.

This seems to be the solution but for some weird reason it’s not working for me. How would i get parts size depending on its rotation? - #4 by nicemike40

Does that work for you? You said no, but you marked it as an answer :slight_smile:

I assumed in that post that the part is only rotated in increments of 90 degrees.

If that’s not the case for you, you’ll have to be more specific about what you want.

Do you want to find the axis-aligned bounding box of a given part?

Well, that should be exactly what I’m looking for, but sometimes somehow it doesn’t give a correct output. Like I’ll randomly rotate a part in the workspace, and measure it, but the script will tell me it’s a different height.

Sure, but what exactly is your desired output? Can you give examples of inputs and outputs?