Edge Detection from Mouse

The ray doesnt know if the edge is hit, it only returns what it hit and the position and the surface normal

So if the ray hits the position of the edge then u could do whatever u want…

The ray will stay active until it hits the edge of the position u want it to hit

Yeah but I would have to have a part at every edge, which is not the way I want to do it…

No, put a part at the edge and measure the position then delete it, in ur script say if the ray hits the position the part was at then so on…

Thats still very inefficient because if I have parts that are not the same size illl have to do that for every single part, also I doubt that would work properly

1 Like

Duplicate the parts?, just scale it to your needs then if the ray hits the position the part was at then so on…

I dont think your understanding what Im trying to achieve, basically I want to get the edge of a part from my mouse position without the need of making parts

@ThoseNamesAreGood Raycasting will help, but not without the use of the surface normal. You can use the surface normal returned to determine the corner.

Hm, could you explain further please

The normal is a vector perpendicular to the tangential surface returned during a raycast operation. For example, (0, 1, 0) is an up vector, (0, -1, 0) is a down vector. You can use the returned normal to get an angle.

Alright but after that what do I do with that angle?

You want to detect the edge, so you can use the angle to determine if the surface is an edge.

https://developer.roblox.com/en-us/api-reference/datatype/RaycastResult

Could you give an example of this at least your kinda of just throwing stuff at me

I do not think you can use a normal of or deduce the angle to help figure out if you hit an edge. An edge isn’t part of a face anyways, it defines a face, so it’d be impossible to actually “hit” the edge literally. You’d need to give a range from 0 to X (like 0.01) studs away from the edge to define as the edge.

Basically, if you’re trying to figure out which edge of a part a Vector3 is closest to, I would do something like this:

  1. Get the position in object space - use local localPos = Part.CFrame:ToObjectSpace(mousePosition).p for that
  2. Check the components of that vector.
  3. (for example) If localPos.X is close to Part.Size.X / 2, then you’re on the right-side face. If localPos.Y is also close to -Part.Y / 2, then you’re also on the bottom-side face. Hurray! Now you know you’re on the right-bottom edge!
1 Like

This would work just fine. This way, you can set a tolerance of what is accepted as the edge and what is not.

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…