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?
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.
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
break
end
end
if isInsideHitbox then
--proc(ess)
end
I will outline the process just to make it easier to figure out what is happening if you execute this code:
-
hitbox
andpoint
variables are defined, this can be parameters to a function where applicable. -
the
point
is redefined in local space relative to thehitbox
, 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 thehitbox'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!
-
-
The
point's
position is checked against all three corresponding axes of thehitbox's
size, and since any two cross-sections from thehitbox
on the same axis will be identical, the check to see if thepoint
is inside the part is very simple, and since the same check will be made between all axes with some modifications, we can use afor
loop to shorten the code. -
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.
-
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 normaland
statements.