- Home /
Getting the z of mouse position?
I'm setting up a "waypoint" system where I click where I want an object to move but when I use:
private Camera cam;
Vector3 point = new Vector3();
Vector3 mousePos = new Vector3();
public Transform particle;
void Start()
{
cam = Camera.main;
}
void OnGUI()
{
Event currentEvent = Event.current;
// Get the mouse position from Event.
// Note that the y position from Event is inverted.
mousePos.x = currentEvent.mousePosition.x;
mousePos.y = cam.pixelHeight - currentEvent.mousePosition.y;
point = cam.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, cam.nearClipPlane));
GUILayout.BeginArea(new Rect(20, 20, 250, 120));
GUILayout.Label("Screen pixels: " + cam.pixelWidth + ":" + cam.pixelHeight);
GUILayout.Label("Mouse position: " + mousePos);
GUILayout.Label("World position: " + point.ToString("F3"));
GUILayout.EndArea();
}
private void Update()
{
if (Input.GetKeyDown("m"))
{
Instantiate(particle, point, Quaternion.identity);
}
}
from Unity Docs but the z its uses is the camera position. Is there a way to get the z in world space?
Answer by Namey5 · Mar 23, 2020 at 09:00 AM
This is fairly similar to a question I answered earlier today;
https://answers.unity.com/questions/1710147/problem-with-screentoworldpoint-keep-getting-the-s.html?childToView=1710363#answer-1710363
The thing is that expressing the z-coordinate in world space just doesn't really make sense. The x and y coordinates are in screen-space, so when they are converted to world-space chances are they will write to the z-coordinate as well. If you want to find the coordinates in relation to your world, the ScreenPointToRay function is much more applicable - from there you can either do a physics raycast against scene objects, or a plane raycast if your scene has a specific plane along which you wish to find the point;
//Position of a point that lies on the plane
public Vector3 planePosition = Vector3.zero;
//Rotation in degrees of the plane's normal (where its face is pointing)
public Vector3 planeRotation = new Vector3 (-90f, 0f, 0f);
...
//z-position doesn't matter
Ray ray = cam.ScreenPointToRay (mousePos);
//Create a new plane
Plane plane = new Plane (Quaternion.Euler (planeRotation) * Vector3.forward, planePosition);
//This will raycast against the physical environment, then fall back to the plane if it misses
if (Physics.Raycast (ray, out RaycastHit hit))
{
point = hit.point;
}
else if (plane.Raycast (ray, out float dist))
{
point = ray.GetPoint (dist);
}
After adding your code (If i added it in the way i was meant to), my object just follows the mouse at a strange offset.
//Position of a point that lies on the plane
public Vector3 planePosition = Vector3.zero;
//Rotation in degrees of the plane's normal (where its face is pointing)
public Vector3 planeRotation = new Vector3(-90f, 0f, 0f);
private Camera cam;
Vector3 point = new Vector3();
Vector3 mousePos = new Vector3();
public Transform particle;
//This is the world space z-coord of the points
float zPosition = 5f;
public Transform unit;
void Start()
{
cam = Camera.main;
}
void OnGUI()
{
Event currentEvent = Event.current;
// Get the mouse position from Event.
// Note that the y position from Event is inverted.
mousePos.x = currentEvent.mousePosition.x;
mousePos.y = cam.pixelHeight - currentEvent.mousePosition.y;
//Z-Position is irrelevant with ScreenPointToRay
Ray ray = cam.ScreenPointToRay(mousePos);
//Create a new plane on the z-axis
Plane plane = new Plane(Quaternion.Euler(planeRotation) * Vector3.forward, planePosition);
//Raycast against the plane
if (plane.Raycast(ray, out float hit))
{
//Find the world pos of our screen point on the plane
Vector3 hitPos = ray.GetPoint(hit);
unit.position = hitPos;
}
point = cam.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, cam.nearClipPlane));
GUILayout.BeginArea(new Rect(20, 20, 250, 120));
GUILayout.Label("Screen pixels: " + cam.pixelWidth + ":" + cam.pixelHeight);
GUILayout.Label("$$anonymous$$ouse position: " + mousePos);
GUILayout.Label("World position: " + point.ToString("F3"));
GUILayout.EndArea();
}
private void Update()
{
if (Input.GetKeyDown("m"))
{
Instantiate(particle, unit.position, Quaternion.identity);
}
}
What exactly is the problem? From what I could understand in the question, that was the desired functionality - to have an object follow the mouse at a specific z-value in world space. If you want the object to be placed on the world-space x/y plane at a specific z-depth, you can change the plane's rotation to [0,0,0].
The problem is that its not on the mouse its above the mouse by a 85 units in the Y rather than at the mouses exact Y position. Red is mouse. Blue is object.
Your answer
Follow this Question
Related Questions
3D mouse position 0 Answers
Off center projection matrix does not move skybox 0 Answers
I need help with a model 0 Answers
CineMachine without Timeline? 1 Answer
How to force the game to be stretched to fit the screen? 1 Answer