ScreenToWorldPoint producing wrong result on rotated camera

I’m trying to return the world coordinates of a input mouse click, but it is producing the wrong world coordinates.

Here what I have

I have a camera Container

Position X = 0
Position Y = 0
Position Z = 0

Rotation X = 30
Rotation Y = 45
Rotation Z = 0

And the Camera

Position X = 0
Position Y = 0
Position Z = -10

Rotation X = 0
Rotation Y = 0
Rotation Z = 0

if (Input.GetMouseButtonUp(0) == true)
       {
        Vector3 mMousePosition = Input.mousePosition;
        mMousePosition.z = -10;
        mMousePosition= Camera.main.ScreenToWorldPoint(mMousePosition);
       }

Now I have a cube at

Position X = 0
Position Y = 0
Position Z = 0

if I select around the centre of the cube, I would of though I would get close to these coordinates but I get

Position x = -12.2817383f
Position y = 9.93985f
Position z = -12.262146f

for example

You actually tell the function to start behind the camera’s view frustum whereas you usually pass a positive value to start with an offset in the camera’s forward direction. I.e. pass in 10 as z-axis value and you’ll be fine for that setup. Of course, if you need it more dynamically (not for the fixed offset) just calculate the distance and pass it instead.

hi @Suddoha

I tried changing the mMousePosition.z= -10; to a positive number 10 but it still is not producing the correct results,

I even tried Camera.main.nearClipPlane but that did not help??

Then I’m not quite sure what you’re trying to achieve.

It sounded as if you wanted to get the mouse’s world position as if you were moving it on a plane that intersects the cube’s origin (in this case also the world origin) and is orthogonal to the camera’s forward direction at the same time…

Camera.main.nearClipPlane is a value that results in the plane which is ‘z’ units away from the camera and fills (or strechtes to the edges of - or however you’d describe that in proper English) the view frustum at this distance (also takes the field of view into account as well). It’s usually set to a small value. Everything between the camera’s position and the near clip plane wouldn’t be rendered.

Now what you were trying sounds as if you wanted such a plane to be z = 10 units in front of your camera, i.e. a centered mouse at (width/2, height/2, 10) would ideally map to (0,0,0). And that should work this way, as long as you haven’t changed anything in your scene.

Actually what I wanted to do was use the mouse position click position, as a direction and get an angle using trig, but as the input mouse is giving wrong results that’s impossible, I know I can raycast into screen but for that to work it needs to hit something to give me the point back so I thought that’s no good.

So what I’m trying to do is get a point in world space from input mouse but I have a rotated camera, we must be able to do it, I’m sure it’s some sort of offset either the camera position because it’s has a parent even though it’s at position 0 on all plains.

I though screentoworld should take care of a rotated camera…00?.

I used -10 because the cameras Z position was -10, and I thought you have to adjust for that if it’s not 0.

I tried your code with 10 and got the results I had expected, clicking onto the cube near it’s approximate center (from that camera perspective) yielded values like (0.0000, 0.0184, 0.0150) which is alreay pretty close.

It’s core functionality and it’s most-likely not broken at all, pretty sure. If you do not get the results you had expected, you must be having some errors in your setup or you’re taking the wrong approach.

@Suddoha

How did you setup the Camera? did you have it like mine e.g a child of a parent at the positions mentioned and the camera rotation, if so could you post the project, I’ve spent hours on this but no luck.

I even setup a camera that was not on a parent and still does not produce the correct world coordinates.

Now in the scene I have three cubes

at these positions

Cube

Position 0,0,0

Player (but its a cube with a material)

Position -4,0,-4

Cube (1)

Position 0, 0, -4

Now don’t forget that Y is actually the Z plain, because the camera is rotated.

I should be able to click on top of these objects(I don’t want to select them), just compare that the mouse click produces the correct coordinates, or close enough.

Thanks.

They all have a different distance from the camera. That cannot work the way you originally tried unless you always calculate the distance to the pointed object (which would most-likely require a raycast), but then you do not click onto the actual surface but rather onto an imaginary plane. Because that’s what you’ll be working with when using ScreentoWorldPoint.

If you want to be able to click the objects and get the point on the surface that you’ve clicked at, simply use a raycast.
All you need for that is a collider on the clickable objects and the ScreenPointToRay method.

We might be able to speed that all up if you further mention:

  • which result would you expect when you click near the approximate center of the object (from the camer’s perspective) => the surface point? the object’s position? a point that is always equally far away from the camera?
  • which result would you expect when you click somewhere else on the object? => still the surface point? or still the object’s position? or still a point that has a fixed distance from the camera?

The first and last options would simply be done with raycasting. The second one could be achieved with your approach.

@Suddoha

I know this sounds really stupid but what I’m actually wanting to do, with Mouse and Touch is the following

Say a player is at position -4, 0 ,-4 “The red cube in the screenshot”, I want to calculate where a person touched on the screen and move (only a single unit) in 1-4 directions (up,right, down, left), I can get the location fine when the camera is not rotated but when it is it just does not work.

to answer your question if I clicked near a objects centre I would expect to see the world space coordinates, it does not matter about selecting the object just so I know that the coordinates system works.

AS I was messing I cheated by place/scaling a cube under the other cubes but the renderer turned off, so I could at least get a hit point, but the hit point was not in world space, I even tried transformPoint.

Its definitely something to do with the parent of the camera set to rotation 30,45,0 or the camera that is set to position z -10

I can send you from a private message the link to the little project.

Thanks for helping.

This should have worked though. You could’ve taken the cubes colliders though, so there’s no actual need for additional invisible ones. If you rather need something like a complete ground/floor, just take a plane, raycast and if you hit something, calculate the direction from the player’s position and the touch position and do whatever math you need to do to get your final movement.

@Suddoha

I think I ended up confusing the hell out of myself, about what I was trying to achieve, I ended up before the end of play last night, creating a form of swipe, actually it’s a tap, more than a swipe which is what I wanted.

I’m sure I’ll confused myself again (it’s an age thing) and waste time, although not fully wasted.

Thank again for your advice it was helpfully especially the camera frustum etc :slight_smile: