Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

ScreenSpace Canvas in VR on Oculus

Discussion in 'AR/VR (XR) Discussion' started by RogueStargun, Sep 19, 2020.

  1. RogueStargun

    RogueStargun

    Joined:
    Aug 5, 2018
    Posts:
    296
    I'm building a targetbox system for a vr game, and I ran into issues with worldToScreenPoint.
    When I'm running the following code with the headset unplugged, it runs fine, but with the headset plugged, its a bit ambiguous which screen it is getting values from.
    The width and height of the target boxes from this function are roughly correct, but the position is incorrect



    Code (CSharp):
    1.  
    2.           public static Rect GetScreenRect(Bounds bounds, Camera cam)
    3.         {
    4.             // Sourced from: https://answers.unity.com/questions/49943
    5.             // optimized!
    6.            
    7.             Vector3 ext = bounds.extents;
    8.             Vector3 cen = bounds.center;
    9.  
    10.             Vector2 min = cam.WorldToScreenPoint(new Vector3(cen.x - ext.x, cen.y - ext.y, cen.z - ext.z));
    11.             Vector2 max = min;
    12.  
    13.             //0
    14.             Vector2 point = min;
    15.             get_minMax(point, ref min, ref max);
    16.  
    17.             //1
    18.             point = cam.WorldToScreenPoint(new Vector3(cen.x + ext.x, cen.y - ext.y, cen.z - ext.z));
    19.             get_minMax(point, ref min, ref max);
    20.  
    21.  
    22.             //2
    23.             point = cam.WorldToScreenPoint(new Vector3(cen.x - ext.x, cen.y - ext.y, cen.z + ext.z));
    24.             get_minMax(point, ref min, ref max);
    25.  
    26.             //3
    27.             point = cam.WorldToScreenPoint(new Vector3(cen.x + ext.x, cen.y - ext.y, cen.z + ext.z));
    28.             get_minMax(point, ref min, ref max);
    29.  
    30.             //4
    31.             point = cam.WorldToScreenPoint(new Vector3(cen.x - ext.x, cen.y + ext.y, cen.z - ext.z));
    32.             get_minMax(point, ref min, ref max);
    33.  
    34.             //5
    35.             point = cam.WorldToScreenPoint(new Vector3(cen.x + ext.x, cen.y + ext.y, cen.z - ext.z));
    36.             get_minMax(point, ref min, ref max);
    37.  
    38.             //6
    39.             point = cam.WorldToScreenPoint(new Vector3(cen.x - ext.x, cen.y + ext.y, cen.z + ext.z));
    40.             get_minMax(point, ref min, ref max);
    41.  
    42.             //7
    43.             point = cam.WorldToScreenPoint(new Vector3(cen.x + ext.x, cen.y + ext.y, cen.z + ext.z));
    44.             get_minMax(point, ref min, ref max);
    45.  
    46.             return new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
    47.         }
    48.  
    49.  
    50.  
    51.         [MethodImpl(MethodImplOptions.AggressiveInlining)]
    52.         static void get_minMax(Vector2 point, ref Vector2 min, ref Vector2 max)
    53.         {
    54.             min = new Vector2(min.x >= point.x ? point.x : min.x, min.y >= point.y ? point.y : min.y);
    55.             max = new Vector2(max.x <= point.x ? point.x : max.x, max.y <= point.y ? point.y : max.y);
    56.         }