Check if players is within bounds of a rotated part

I’m used to doing this with blocks that aren’t rotated, or at least with the simplicity of being 45 degrees. How can I make this work with a block that has any orientation?

1 Like

The easiest solution is to use EgoMoose’s Rotated region 3 module. It’s well documented with a quick guide on how to use it inside the script, and allows you to do things like collision detection between boxes, and IIRC also spheres. I’ve used it in a couple of projects and have been very pleased with it.

1 Like

If you want to make a position, like a player’s HRP position, relative to a part, the CFrame:Inverse method is your best friend.

local hitbox = --block part
local point = --Vector3

--Creates a new point that is relative to the CFrame to check
local relativePoint = hitbox.CFrame:Inverse() * point

Imagine this like multiplying the hitbox's CFrame by it's inverse to place it
at (0,0,0) , but applied to the point instead!

local isInsideHitbox = true

--optimized from rP.X, rP.Y, and rP.Z all being checked in the same way
for _,axis in ipairs{"X","Y","Z"} do

	--optimized from rP.X > size.X/2 or rP.X < -size.X/2
	if math.abs(relativePoint[axis]) > hitbox.Size[axis]/2 then
		isInsideHitbox = false

if isInsideHitbox then

I will outline the process just to make it easier to figure out what is happening if you execute this code:

  1. hitbox and point variables are defined, this can be parameters to a function where applicable.

  2. the point is redefined in local space relative to the hitbox, which allows for a couple imagined properties:

    • The hitbox is now at the center of the world, and any offset from world space is converted to the part’s local space.

    • Because of this, checking the point against the hitbox's size – along with an offset – will be exactly the same as checking the point against its position and size in world space, because the position has been taken out of the equation!

  3. The point's position is checked against all three corresponding axes of the hitbox's size, and since any two cross-sections from the hitbox on the same axis will be identical, the check to see if the point is inside the part is very simple, and since the same check will be made between all axes with some modifications, we can use a for loop to shorten the code.

  4. The final optimization made is that since the hitbox in local space is symmetrical on all three X Y and Z planes, we can use an absolute value to compare opposite faces of a block at the same time.

  5. Finally, the boolean system put in place is essentially an and statement implemented into a loop: if any argument inside the loop is evaluated to false, the whole statement is false, and the statement is “shortcutted,” just like how lua evaluates normal and statements.