Edge Detection from Mouse

Untested, but I got bored so this should do it:

-- Given a part and a position, returns which faces the position lies on or is
-- within `epsilon` studs of.
-- @returns a Faces object: https://developer.roblox.com/en-us/api-reference/datatype/Faces
local function WhichFaces(part, position, epsilon)
    epsilon = epsilon or 0.1
    
    local pos = part.CFrame:ToObjectSpace(position)
    
    local halfSize = part.Size / 2
    
    -- first check that we're within the part's outside bounds
    if math.abs(pos.Y) < halfSize.Y + epsilon
        and math.abs(pos.Z) < halfSize.Z + epsilon
        and math.abs(pos.X) < halfSize.X + epsilon
        then
        
        local faces = {}
        
        -- check if we're close to an edge
        if pos.Y > halfSize.Y - epsilon then table.insert(faces, Enum.NormalId.Top) end
        if pos.Y < epsilon - halfSize.Y then table.insert(faces, Enum.NormalId.Bottom) end
        
        if pos.Z > halfSize.Z - epsilon then table.insert(faces, Enum.NormalId.Back) end
        if pos.Z < epsilon - halfSize.Z then table.insert(faces, Enum.NormalId.Front) end
        
        if pos.X > halfSize.X - epsilon then table.insert(faces, Enum.NormalId.Right) end
        if pos.X < epsilon - halfSize.X then table.insert(faces, Enum.NormalId.Left) end
        
        return Faces.new(unpack(faces))
    else
        return Faces.new()
    end
    
end

-- USAGE e.g.

local mousePosition = Vector3.new(1, 1, 0)
local myPart = workspace.Part

local faces = WhichFaces(myPart, mousePosition)

if faces.Top then
    print("Top face!")
    
    if faces.Front then
        print("Top-front edge too!")
        
        if faces.Right then
            print("Top-front-right corner!")
        end
        
    elseif faces.Left then
        print("Top-left edge!")
    end
    -- etc.
end

6 Likes

But this is assuming that all parts are rectangular, doesn’t account for unions nor mesh parts, nor wedges, nor spheres, nor cylinders, right?

I have an idea
how about do

local a1 = part.Size + (Part.Position/2)
local a1 = part.Size - (Part.Position/2)

Or something like that
using region three I think it’s possible!

1 Like

How can i get this to work correctly…