- Home /
Camera Screen to world point returns cameras transform position.
Debug.Log (Camera.main.ScreenToWorldPoint(Input.mousePosition));
is just giving me the transform of the camera, no matter where my mouse is on screen. Any ideas? Thank you.
This is such an inconsistency by Unity. They ask the screen position to be supplied with the Z, while for screen position it makes absolutely no sense. I can see the explanations here, but they're rather intuitive, and not mathematically formal. Screen is flat and has no depth and therefore no Z! All the mouse/touch points are already there, and speaking of the world coordinates, are necessarily at the clipping plane! One could argue this is a na$$anonymous$$g problem, that the method could be called ViewportToWorldPoint or smth, but its actually not. They want you to have two of the three coordinates in screen space, and one in the actual world space. How more inconsistent could it be to provide different components of the same Vector3 in different coordinate systems? As much as I love Unity3D, as much its API is a huge chunk of mess. Radians vs degrees, coordinate systems, Vector3 vs Vector2, you name it...
So how is this resolved? How do I get ScreenToWorldPoint without passing in the camera z position, and switch in the object's z position?
Still not working for me, the z is different to the camera's z, but the object still follows the camera's x and y ins$$anonymous$$d of the mouse.
Answer by Huacanacha · Oct 20, 2013 at 07:52 AM
As others have pointed out you need Z, which is the distance from the camera. To get the true world point on the cameras viewing plane you should use the clipping plane distance:
Debug.Log(Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
Input.mousePosition.y, Camera.main.nearClipPlane)));
I believe if you use 0 you will just get the camera's position, as X and Y are irrelevant when scaled to zero. The viewing plane at the cameras origin is a singularity ;)
If my near plane is 0.2, that would be 0.2 away from Camera position.
That's correct... the virtual 'window' you are viewing through is 0.2 in front of the camera if the near clip plane is 0.2. The original problem was that ScreenToWorldPoint was returning the cameras position, which will always be the case when Z is zero.
The viewport is a projection of the rectangular viewing window that exists at nearClipPlane distance forward of the camera. For non-orthographic projections the further you get from the camera the larger this 'window' is in world space, but Everything will look exactly the same (as the camera projection is the same) regardless of the clip plane distance except that objects are cutoff closer or further from the camera.
It's implied by the fact that the OP doesn't want the Camera position (this was their problem in the first place) and the fact they're looking for the point on the screen in world space, according to the function they've chosen... the only logical positions for this could be the camera position (not in this case) or the XY point on the near clip plane.
The function you linked, ScreenToViewportPoint, doesn't give the point in world space. It just normalizes input to [0,1] range and flips the vertical axis (ok it also fills in Z which I assume will be the near clip distance).
Reverted and cleaned, at your request :)
Your supporting comments make yours the better answer ;)
Answer by pajamajama · Oct 20, 2013 at 07:39 AM
Just found out that you need to supply a z position for it to work. http://answers.unity3d.com/questions/18205/World-mouse-position-not-depending-on-Screen-mouse-position.html
mousePos = Input.mousePosition;
mousePos.z = 1.0;
worldPos = Camera.main.ScreenToWorldPoint(mousePos);
Using 1 for z gives the projected X,Y point at 1 unity from the camera. To get the point on the clipping plane use camera.nearClipPlane. See my full answer below.
Answer by mandisaw · Jan 13, 2018 at 03:39 PM
The input z-coordinate is the key, but it should actually be equal to the Y-axis distance from the Camera to the object being moved. That distance is only equal to Camera.nearClipPlane if your scene configuration happens to have your scene at the Camera's near clip plane.
void OnMouseDrag() {
// ScreenToWorldPoint requires distance to Camera as z-coordinate, otherwise it only returns current, fixed Camera position (distanceToCamera = 0)
Vector3 screenPosition = Input.mousePosition;
screenPosition.z = Camera.main.transform.position.y - transform.position.y;
Vector3 worldPosition = Camera.main.ScreenToWorldPoint (screenPosition);
transform.position = worldPosition;
}
Answer by meat5000 · Oct 20, 2013 at 07:42 AM
Debug.Log (Camera.main.ScreenToWorldPoint(Vector3(Input.mousePosition,0)));
Z element is depth. As Huacanacha says, z = 0 is Camera position and Camera.main.nearClipPlane is the viewport in world space.
http://docs.unity3d.com/Documentation/ScriptReference/Camera.ScreenToWorldPoint.html
Did you want
http://docs.unity3d.com/Documentation/ScriptReference/Camera.ScreenPointToRay.html
instead?
Answer by aeroson · Dec 12, 2015 at 11:44 AM
So I had exactly the same code as yours. The bug was that I did set camera position multipler times in multiple scripts. Camera position changed by script X that is should not do, then player target direction computed from camera with ScreenToWorldPoint, then camera position changed to look at player. Result is camera looks at player everything looks fine, but the aiming seems like there is a bug in ScreenToWorldPoint. Tried disabling random scripts and it worked. That way I found out which one does it.
That doesn't really answer the question. Are you sure you read the other answers? A screen point is a 2d point. When you want to "unproject" it you have to supply a depth value. That's the problem in the code in question.
OP doesnt say if he uses orthographic or perspective camera, in my case (orthographic) the Z seem to not matter.
Well, he doesn't say that he's using a perspective camera, however the symptoms he has clearly verifies that he's using a perspective camera since at distance 0 all points map to the camera origin.
Of course the result would be different when you use an orthographic camera, however you're still required to supply a z value. If your game is a 2d game and everything is at distance 0 and the camera is not rotated then z doesn't matter. You would implicitly pass "0" as z value and get back 0 as z position.