I want to move a transform to a point just off a surface. I figured out how to do it with two rays, but I was wondering if there’s a more performant way:

// Layer is the layer of the surface I care about. MAX_DIST is the maximum magnitude of the ray (the width of the 2d game board).
public static Vector2 TouchPoint(Vector2 origin, Vector2 direction) {
RaycastHit2D hit = Physics2D.Raycast(origin, direction, MAX_DIST, 1 << Layer);
if (hit.collider) {
Ray2D ray = new Ray2D(origin, direction);
return ray.GetPoint((origin - hit.point).magnitude - .01f);
}
return Vector2.zero;
}

Hmmm. You are not telling us why you would want to do this, so we may not be able to give you an optimal answer. First, an Observation: you are looking for a point beneath a surface, but you are returning a 2d point, not 3d. You seem to make some assumptions about the surface that you are not telling us.

Generally speaking, if you have a surface, to get a point that is a distance d beneath the surface at a point P, the best approach is to take the surface’s normal at P (make sure the normal is normalized, i.e. has the Magnitude of 1.0) and multiply that normal with d. Add the resulting vetor to P (or subtract, depending on which side of the surface you want and how your surface is defined) and you have your point above/below the surface.

I should have been more clear – I’m looking for a point just above (not below) the surface, and it’s a 2d surface (for a 2d game).

Will multiplying vectors and surface normals like you suggest be more efficient than using a Ray2D like I’m doing above? I don’t know how Ray2D is implemented, but it feels similar to what you’re describing.

I don’t want to come off as a smarta**, but what is a ‘2D surface’? Isn’t that a line? I think you probably have a surface that is parallel to the Unity standard XZ surface (Y=0), so this is perhaps one of the assumptions you have made. In any event. you will not be running up against a performance issue with just a couple of vector multiplications, so just have at it. A point just above a surface is usually one that you get by multiplying 0.001 with the surface normal and adding it to a point that lies on the surface (this will give a point 1 mm above the surface). But if Rays feel more natural to you, use them. Everything’s fine as long as you get where you want

A 2D surface doesn’t have to be a line; it’s whatever shape (in my case, a complex polygon) on which characters walk in a 2D game. Yes, I get that, mathematically, a “surface” is a two-dimensional shape curved in three dimensions, but I have no trouble living with myself after calling a 1D curve in 2-space a “surface” too.

I benchmarked the two approaches, and multiplying by the surface normal is roughly 3x as fast as using Ray2D. Thanks for the help!