Roblox doesn’t give you this directly, but here’s a practical way to do it:
The Basic Idea
Every part has six faces: front, back, left, right, top, bottom.
When the player touches the part, you get their position (or the position of the part that touched).
You compare this position to the center points of each face.
The face with the smallest distance to the player is probably the one being touched.
How To Do It (Example)
Here’s a simple function you can use. Plug in the position you want to check (like the player’s HumanoidRootPart.Position
) and the part they’re touching:
function getClosestFace(pos, part)
local faces = {
Top = part.CFrame * CFrame.new(0, part.Size.Y/2, 0),
Bottom = part.CFrame * CFrame.new(0, -part.Size.Y/2, 0),
Front = part.CFrame * CFrame.new(0, 0, -part.Size.Z/2),
Back = part.CFrame * CFrame.new(0, 0, part.Size.Z/2),
Right = part.CFrame * CFrame.new(part.Size.X/2, 0, 0),
Left = part.CFrame * CFrame.new(-part.Size.X/2, 0, 0),
}
local closest = nil
local minDist = math.huge
for face, cframe in pairs(faces) do
local dist = (pos - cframe.Position).Magnitude
if dist < minDist then
minDist = dist
closest = face
end
end
return closest
end
Usage Example:
local playerPos = player.Character.HumanoidRootPart.Position
local touchedPart = -- the part the player touched
local side = getClosestFace(playerPos, touchedPart)
print("Player is touching the", side, "side")
Real Talk
This works best if the player is actually near the part’s surface—not floating in the middle of nowhere.
It’s not perfect at corners or edges, but for most uses (like buttons, doors, etc.), it does the job.
If you want pixel-perfect accuracy, you’ll need more complex math, but honestly, this is good enough for 99% of games.
Let me know if you need further help or have informations!