Converting mouse position to world position with ScreenToWorldPoint() always give position of camera

I have a Grid based game where I handle clicks on grid with mouse position and edit them based on mouse position flored to integer.

When using ScreenToWorldPoint() passing Input.mousePosition I always get same value even when mouse is moved.

On click grid cell that player click should increment it’s value by 1 but anywhere I click only one in center of screen gets changed meaning if I move camera another cell will change it’s value.

Only solution I found is to manually set point.z to anything needed, I tried with 0f, 1f, and lastly with a negative Z position of Camera, and always got same result with different Z values.

In Debug.Log(point + " " + Input.mousePosition); point is always same (50.00, 50.00, 100.00) and Input.mousePosition changes depending on where player clicks and on screen resolution.

Here is code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Testing : MonoBehaviour {

    private Grid grid;
    private Vector3 point;

    private void Start() {
        grid = new Grid(10, 10, 10f, new Vector3(0, 0));
    }

    private void Update() {
        HandleClickToModifyGrid();

        if (Input.GetMouseButtonDown(1)) {
            Debug.Log(grid.GetValue(Camera.main.ScreenToWorldPoint(Input.mousePosition)));
        }
    }

    private void HandleClickToModifyGrid() {
        if (Input.GetMouseButtonDown(0)) {
            
            point = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            point.z = -Camera.main.transform.position.z;
            int value = grid.GetValue(point);
            grid.SetValue(point, value + 1);
            Debug.Log(point + "  " + Input.mousePosition);
        }
    }

}

>Solution :

In general ScreenToWorldPoint takes a Vector3 where

The z position is in world units from the camera.

Meaning how much in front of the camera your world position should be.

You are passing in a Vector2 so when that is implicitly converted to a Vector3 the z component will be 0 => point will always be on the cameras plane.


I don’t know exactly how your Grid works but you might be better using a Plane and Plane.Raycast like e.g.

// A XZ plane going through 0,0,0
var plane = new Plane(Vector3.up, Vector3.zero);

var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(plane.Raycast(ray, out var distance))
{
    var point = ray.GetPoint(distance);

    ...
}

Leave a Reply