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.
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
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.
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.
// returns percentage of camera height, returns -1 if no collider, 0 if obj off screen
float GetObjectCameraHeight (Camera theCamera, GameObject theObj) {
Vector3 cMin;
Vector3 cMax;
Collider col;
Plane[] planes;
col = theObj.GetComponent<Collider>();
if (!col)
return -1.0f;
planes = GeometryUtility.CalculateFrustumPlanes(theCamera);
if (!GeometryUtility.TestPlanesAABB(planes, col.bounds)) // check if it's off screen
return 0.0f;
cMin = theCamera.WorldToScreenPoint(col.bounds.min);
cMax = theCamera.WorldToScreenPoint(col.bounds.max);
cMin.x -= theCamera.pixelRect.x; // adjust for camera position on screen
cMin.y -= theCamera.pixelRect.y;
cMax.x -= theCamera.pixelRect.x;
cMax.y -= theCamera.pixelRect.y;
return Mathf.Abs((cMax.y - cMin.y) / theCamera.pixelHeight);
}