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

WorldToScreenPoint and WorldToScreenPoint returning weird values on VR camera [Solved]

Discussion in 'AR/VR (XR) Discussion' started by keenanwoodall, Mar 9, 2020.

  1. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    597
    When a certain object is out of the players view I want to give a visual indication in front of the player of where it may be.

    I've written a simple test script for this. The script has has fields for a target object and camera. It places its transform in front of the camera and offsets from the center of the view in the direction of the target object in screenspace.

    2020-03-09_15-15-41.gif

    As you can see, this works quite well with a normal camera. Unfortunately it doesn't work well when using a camera that targets the HMD instead of the main display.

    2020-03-09_15-20-43.gif

    The "center" of the screen appears to be the bottom left of the screen which breaks the calculations.
    Any advice is greatly appreciated, and let me know if more info is needed!

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class OffscreenIndicator : MonoBehaviour
    4. {
    5.     public Transform targetObject;
    6.     public Camera hmdCamera;
    7.     [Space]
    8.     public float radius = 200f;
    9.     public float depth = 0.5f;
    10.  
    11.     private void LateUpdate()
    12.     {
    13.         Vector3 screenPosition = GetScreenPoint();
    14.         Vector3 screenCenter = new Vector3
    15.         (
    16.             Screen.width * 0.5f,
    17.             Screen.height * 0.5f,
    18.             0f
    19.         );
    20.  
    21.         Vector3 offsetFromCenter = screenPosition - screenCenter;
    22.  
    23.         Vector3 direction = offsetFromCenter.normalized;
    24.         Vector3 targetOffsetFromCenter = direction * radius;
    25.    
    26.         if (screenPosition.z < 0f)
    27.             targetOffsetFromCenter *= -1f;
    28.    
    29.         Vector3 targetScreenPosition = targetOffsetFromCenter + screenCenter;
    30.         targetScreenPosition.z = depth;
    31.    
    32.         transform.position = hmdCamera.ScreenToWorldPoint(targetScreenPosition, Camera.MonoOrStereoscopicEye.Mono);
    33.     }
    34.  
    35.  
    36.     private Vector3 GetScreenPoint()
    37.     {
    38.         return hmdCamera.WorldToScreenPoint(targetObject.transform.position, Camera.MonoOrStereoscopicEye.Mono);
    39.     }
    40. }

    [edit] I've tried Right and Left in addition to Mono when calling WorldToScreenPoint and ScreenToWorldPoint but neither fixed anything

    [final edit] The issue was that Screen.width and Screen.height return the dimensions of the game view window, not the hmd screens. The solution is to use the pixelWidth and pixelHeight of the relevant camera
     
    Last edited: Mar 9, 2020
    ShantiB95 likes this.