Screen point to point on Plane WITHOUT Raycast?

How do I use the position taken from Input.mousePosition, take a gameobject (which is a plane), and calculate the local space point on the plane (or world point on the plane doesn’t matter)? I can see why raycast would be useful with multiple gameobjects, but I only have one and I’m sure there is another way without using it, whether it be built in or an algorithm. Thanks for your help.

The trickiest part is converting a 2d point on the screen into a 3d direction. Luckily, Unity is kind enough to provide you a nifty algorithm to do this: Camera.ScreenPointToRay which will give you a Ray, essentially a start point (the camera’s position) and a direction. Assuming that your plane is horizontally flat, all you have to do is solve a linear equation.

You can find the delta between the ray’s start point’s y position and the plane’s y position and multiply that by the direction of the ray to find how much the position as changed. Then normalize the direction by its y position and… Okay, this is getting kind of confusing to. Here’s an example:

Plane plane = new Plane();
Camera camera = new Camera();

void Start()
{
    plane.transform.position = Vector3.zero;
    camera.transform.position = Vector3.up * 15;
}
  
void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        Nuke (GetIntersectionPos (plane, camera));
    }
}
  
Vector3 GetPlaneIntersection(Plane plane, Camera camera)
{
    Ray ray = camera.ScreenPointToRay(Input.MousePosition);
    float delta = ray.origin.y - plane.transform.position.y;
    Vector3 dirNorm = ray.direction / ray.direction.y;
    Vector3 IntersectionPos = ray.origin - dirNorm * delta;
    return IntersectionPos;
}

Sorry for necro. But I think it is better to use Plane.Raycast function. It is just a Plane’s function and does nothing with colliders. The code could be something like this:

public static bool TryScreenToPlanePoint(this in Plane plane, in Vector2 screenPoint, Camera cam, out Vector3 point)
{
    Ray ray = cam.ScreenPointToRay(screenPoint);
    if(plane.Raycast(ray, out var enter))
    {
        point = ray.GetPoint(enter);
        return true;
    }
    point = default;
    return false;
}