Search Unity

World Size to Screen Size

Discussion in 'Scripting' started by John-B, Dec 11, 2018.

  1. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,262
    I can find the position of a 3D object on screen with WorldToScreenPoint, but how do I find the object's size on screen? How do I convert a mesh's or a collider's bounds, which are in world units, to screen space pixels? I need to know what percentage of the screen's width and height an object occupies.
     
  2. ZombieTFK

    ZombieTFK

    Joined:
    Sep 6, 2016
    Posts:
    55
    Hmm, I'm not 100% sure, but as an idea, if all you need is an approximation maybe you could use Renderer.bounds to get the AABB of the rendered object, and then convert each point using WorldToScreenPoint, and then you'd be able to get the resultant components of the box? You'd have to make sure no points are off the screen etc. etc. though, sounds like a pain.

    Personally, I think what this guy suggests in his answer seems fairly straightforward.

    Another option; Maybe you could change the shader used by the object to a certain color, and then render it to a rendertexture, and then read all the pixels in the rendertexture vs a background color
     
  3. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,262
    Thanks. I figured I could calculate the size point by point using bounds, but I thought there might be a more direct way, like a WorldToScreenExtents function I was not aware of, since objects with LODs need to know how much screen space they occupy.
     
  4. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,262
    Here's a simple function I came up with that works well, for me. It should work with any camera, any viewport rect. All of my objects have a box collider attached to the parent; if your objects have multiple colliders, you'd have to combine (Encapsulate) their bounds first. You could also use renderer bounds if your object doesn't have a collider. You could get camera width by swapping a few x's and y's.

    Code (CSharp):
    1. // returns percentage of camera height, returns -1 if no collider, 0 if obj off screen
    2.  
    3. float GetObjectCameraHeight (Camera theCamera, GameObject theObj) {
    4.     Vector3 cMin;
    5.     Vector3 cMax;
    6.     Collider col;
    7.     Plane[] planes;
    8.  
    9.     col = theObj.GetComponent<Collider>();
    10.     if (!col)
    11.         return -1.0f;
    12.  
    13.     planes = GeometryUtility.CalculateFrustumPlanes(theCamera);
    14.     if (!GeometryUtility.TestPlanesAABB(planes, col.bounds)) // check if it's off screen
    15.         return 0.0f;
    16.  
    17.     cMin = theCamera.WorldToScreenPoint(col.bounds.min);
    18.     cMax = theCamera.WorldToScreenPoint(col.bounds.max);
    19.  
    20.     cMin.x -= theCamera.pixelRect.x;  // adjust for camera position on screen
    21.     cMin.y -= theCamera.pixelRect.y;
    22.     cMax.x -= theCamera.pixelRect.x;
    23.     cMax.y -= theCamera.pixelRect.y;
    24.  
    25.     return Mathf.Abs((cMax.y - cMin.y) / theCamera.pixelHeight);
    26. }
    27.  
     
    Last edited: Jan 8, 2019
    joelsinbarba likes this.