Trying to find the closest part

Hello, I am trying to make an auto lock-on grappler where it automatically locks on to the closest part to the players mouse. So for an example in this image, my mouse is closer to part 2 than part 1, so it should lock to part 2 instead of part 1. how would I achieve this?
example image

You could try using a mouse raycast and setting something up with this code snippet i found in the forums

you should use UserInputService and MouseRaycast for that.

workspace:Raycast()
-- for example

Using raycasting for this type of problem will not work. It’s unrelated to what you’re trying to achieve.


Luckily, Roblox gives us API to solve this problem. This API is called WorldToScreenPoint, which is a method of the Camera class. This method takes a 3D point in the world and tells you where that point is on the screen (basically, it transforms a 3D point to a 2D point).

Knowing this, we can get the 3D positions of the two parts:

local part1WorldPos = Part1.Position
local part2WorldPos = Part2.Position

Then, you can use WorldToScreenPoint to determine where the point lies on the screen:

local Camera = workspace.CurrentCamera

local part1ScreenPos = Camera:WorldToScreenPoint(part1WorldPos)
local part2ScreenPos = Camera:WorldToScreenPoint(part2WorldPos)

Now, you can get the distance of the screen positions with the mouse position:

local mousePos = UserInputService:GetMouseLocation()

-->> .Magnitude gets the length of the vector
-->> converting to Vector2 as GetMouseLocation returns a Vector3
local part1Distance = (mousePos - Vector2.new(part1ScreenPos.X, part1ScreenPos.Y)).Magnitude
local part2Distance = (mousePos - Vector2.new(part2ScreenPos.X, part2ScreenPos.Y)).Magnitude

Lastly, you can compare the distances. The smallest distance is the closest part:

if part1Distance < part2Distance then
    print("Part1 is closer to the mouse!")
else
    print("Part2 is closer to the mouse!")
end
Full code
local Camera = workspace.CurrentCamera
local mousePos = UserInputService:GetMouseLocation()

-->> world positions
local part1WorldPos = Part1.Position
local part2WorldPos = Part2.Position

-->> screen positions
local part1ScreenPos = Camera:WorldToScreenPoint(part1WorldPos)
local part2ScreenPos = Camera:WorldToScreenPoint(part2WorldPos)

-->> distance from mouse
local part1Distance = (mousePos - Vector2.new(part1ScreenPos.X, part1ScreenPos.Y)).Magnitude
local part2Distance = (mousePos - Vector2.new(part2ScreenPos.X, part2ScreenPos.Y)).Magnitude

if part1Distance < part2Distance then
    print("Part1 is closer to the mouse!")
else
    print("Part2 is closer to the mouse!")
end
4 Likes

Thank you! This was the solution, the only problem I had was that I got an error, and that’s because the part1ScreenPos was a vector3, so the only thing that needed to be changed was

local part1Distance = (mousePos - part1ScreenPos).Magnitude
local part2Distance = (mousePos - part2ScreenPos).Magnitude

to

local part1Distance = (mousePos - Vector2.new(part1ScreenPos.X, part1ScreenPos.Y)).Magnitude
local part2Distance = (mousePos - Vector2.new(part2ScreenPos.X, part2ScreenPos.Y)).Magnitude

Thank you again!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.