Search Unity

Screen positions incorrect when using pixel perfect camera

Discussion in '2D' started by sballew7, Apr 7, 2021.

  1. sballew7

    sballew7

    Joined:
    Sep 3, 2013
    Posts:
    76
    Hi all,

    I'm encountering an issue where using my URP pixel perfect camera to map a screen point to a ray is producing incorrect results.

    Consider the following code, which uses the Enhanced Touch API to receive a Touch instance.

    Code (CSharp):
    1.  
    2. private bool IsTouchingSelf(Touch touch)
    3.         {
    4.             Ray raycast = Camera.main.ScreenPointToRay(touch.screenPosition);
    5.             Debug.DrawRay(raycast.origin, raycast.direction.normalized * 15, Color.red, 5f);
    6.            
    7.             var hit = Physics2D.Raycast(
    8.                 raycast.origin,
    9.                 raycast.direction,
    10.                 Mathf.Infinity,
    11.                 targetLayers);
    12.            
    13.             if ((hit.collider != null ? hit.collider.gameObject : null) == gameObject)
    14.             {
    15.                 return true;
    16.             }
    17.  
    18.             return false;
    19.         }
    20.  
    When running this, the ray is drawn in a location a few units away from where the touch actually occurred. This is in the editor when the game view is in a tab.

    If I maximize the game view, it works as expected. Further, if I disable the Pixel Perfect component on the camera, it again works as expected.

    Has anybody encountered this? Should I be doing something other than `ScreenPointToRay` to account for pixel perfect camera modifications?

    Thanks!
     
  2. Blake067

    Blake067

    Joined:
    Nov 9, 2017
    Posts:
    4
    I encountered same issue:(
     
  3. Blake067

    Blake067

    Joined:
    Nov 9, 2017
    Posts:
    4
    I found the reason, the pixel perfect camera's "Crop Frame" was turned on, which caused the camera's ViewPort Rect be modified.
    Code (CSharp):
    1.  
    2.         // pointer = inputAction.ReadValue<Vector2>();
    3.         public Vector2 CorrectByRect(Camera camera, Vector2 pointer)
    4.         {
    5.             var size = camera.rect.size;
    6.             var offset = camera.pixelRect.position;
    7.             return new Vector2(pointer.x * size.x + offset.x, pointer.y * size.y + offset.y);
    8.         }
     
    Last edited: Oct 23, 2021