How to find closest point on a ray

Hello fellow Roblox developers.

I am currently in the midst of creating a weapon system for my wizard-type game. The weapons work like any other weapon, using raycasting. But, I am not using Ray.New(), I am using the new (and "Better) worldroot:Raycast().
They work pretty much the same, but some functions are not on the worldroot:Raycast(). But anyways, this is not the important part.

When shooting at someone, you don’t need to hit them exactly. In other words, you can shoot 5 studs to either side of the character and still be awarded points. It’s essentially a bigger hitbox (in a way). But, it’s also for some other reasons that are not important to state here (feel free to ask). So, I think I better show some pictures to describe. I described here also.

So basically I want to get the side distance from a ray to a certain position like so:
Say a ray shoots like this:
image

I would like to get the distance between the closest point of the ray and the character: (see green marking)
image

Now, I managed to do something like that:

(Images:

The red part basically finds the closest position, and then you can just do the magnitude between them and you get something like this:
image

But the harder part is when the ray is at an angle:



Now it will bascially also account for the height change, so the magnitude/Distance will be much greater.
Since now it gets this distance:


But I want this distance:

I just want the distance from the side, if you get what I mean. It’s a little hard to explain, but I did my best.

If you have more questions, please feel free to ask! It would mean the world to me if you guys helped me. Thanks!

Edit:
Thinking about this now, it’s quite easy to exploit. If anyone has other ideas, i’d be more than open to them.

1 Like

Hmm, if you don’t want the height, just remove it by multiplying it by Vector3.new(1,0,1) to remove the y-height value then you get the magnitude of that value.

Still I’m not exactly sure what you meant by the image below:

I mean that’s an optical illusion, you could continue turning the camera until the part is behind the ray and the “distance” from line to point would be zero.

I believe you meant distance on the 2d XZ plane which is the birds eye view of the baseplate. If so you can also just times the direction of line ray you want to compare to with the Vector3.new (1,0,1) trick to remove the vertical angle component entirely and make the line entirely flat on the baseplate.

Exactly what I meant.

I will try out your ideas as soon as I can. Thanks

I’ve never been good at algebra but you’d have to solve the parametric ray equation for the dot product. So like it’d be like

0=rayDirection:Dot((rayOrigin+(rayDirection*t)) - point)

I suck at algebra but you’d have to rearrange the equation so that the equation equals t, then solve for t. Then the position of the closest point on a ray is

closestPoint = rayOrigin+(rayDirection*t)
1 Like

Have you considered Ray:ClosestPoint? :slight_smile:

1 Like

This isn’t what we are talking about, bud

Fair enough, bud :wink: lemme try again

local function ClosestPointXZ(ray, point)
	local p = Vector2.new(p.X, p.Z)
	local origin = Vector2.new(ray.Origin.X, ray.Origin.Z)
	local dir = Vector2.new(ray.Direction.X, ray.Direction.Z).Unit
	local point = origin + dir * (p-origin):Dot(dir)
	return (point-p).Magnitude
end
2 Likes

If that works then thats poggies

Thanks @nicemike40 and @CoderHusk.
All the math was too tedious and advanced, that I actually switched back to the old legacy raycast (and used the function @nicemike40 proposed)

Too bad Roblox removed all the built-in functions for the new worldroot:Ray(). It’ll make people choose the legacy over the new one.

1 Like