- Home /
 
Orthographic camera with rotation and ScreenToWorldPoint
I have an ortho camera which used to have no rotation. When I used
 ScreenToWorldPoint(Input.mousePosition)
 
               I would get the desired result. I have a grid of tiles and I would use this to place a graphic over the tile that was under the mouse.
However, now that I have added some rotation to the camera, the selected tile isn't actually the one that is under the mouse. I realise that this is to do with rotation and some answers I have already looked at suggest setting the Z to the cameras near clipping plane like so:
 Vector 3 mousePosition = Input.mousePosition;
 mousePosition.z = Camera.main.nearClipPlane;
 Vector3 position = Camera.main.ScreenToWorldPoint(mousePosition);
 
               However, this doesn't work and produces the same results if I left the Z axis alone.
Answer by SteenPetersen · Feb 05, 2018 at 04:29 PM
Ok Here is how I fixed it in my Game hope this helps. Lassade was correct btw here is how you do it:
You need to spin up a plane so that you can cast a ray at it in order to determine what the distance is from the camera.
So in my game I have a -30 rotation on the X of the camera which is ultimately means the 'world' is further from the top of the screen than it is from the bottom. That means that if I want to shoot a projectile say at the mouse. I need to know the exact mouse click position.

What I did was spin up a Plane in the same position as my world and cast a ray at it to determine what distance it was from the camera.
 // define a plane variable
 // may be Vector3.up in your case depending on your camera orientation
 Plane plane = new Plane(Vector3.forward, Vector3.zero);
 
 // Shoot a ray at it when your event happens, in my case projectile
 
 public void OnCastComplete()
     {
 var projectile = Instantiate(projectile, somePoint.transform.position, transform.rotation);
 
         //Create a ray from the Mouse click position
         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         //Initialise the enter variable
         float enter = 0.0f;
 
         if (plane.Raycast(ray, out enter))
         {
             Debug.Log("distance " + enter);
             //Get the point that is clicked
             Vector3 hitPoint = ray.GetPoint(enter);
             //Draw a debug ray to see where you are hitting
             Debug.DrawRay(ray.origin, ray.direction * enter, Color.green);
 
             // create a direction vector (hitPoint => somePoint
             Vector2 direction = new Vector2(
                 hitPoint.x - somePoint.transform.position.x,
                 hitPoint.y - somePoint.transform.position.y
                 );
 
             // addforce force to the projectiles rigidbody in that direction.
             projectile.AddForce(direction * projectileSpeed);
 
         }
 
     }
 
 
               Hope this clears it up a bit. This will certainly help in my game and it took me a long time to find the solution so I hope it helps others.
Answer by lassade · Jan 26, 2018 at 05:58 PM
I think you have an complex rotation on your camera, like in the one of a isometric game, in this case you should convert your sceen point to ray then raycast it on a plane (look at Plane class) or in the collider geomtry of your game.
Thanks for the info. The game has no colliders, each tile is just a sprite.
I have a very similar problem and cannot seem to fix it, trying to work on it at the moment will update if I find a solution.
Your answer
 
             Follow this Question
Related Questions
Is there any way to create a fade effect in order to hide what isn't rendered by the camera? 0 Answers
3rd Person Camera clips through walls 0 Answers
ScreenToWorldPoint not working 1 Answer
Camera.main.ScreenToWorldPoint not outputting expected results. 1 Answer
Near clipping plane is different when game is maximized 0 Answers