I am working on a 2D game in which an Orthographic camera with variable size follows the player. I have a script that disables certain components (such as colliders and 2D shadow casters) when their objects are outside of a certain radius of the camera in order to increase performance.
Ideally, this radius should large enough that this is not visible on camera, but still as small as possible as to get the best performance levels possible. However, the orthographic size of the camera will be variable, so I cannot just use a fixed number for the radius.
Is there a way to convert Screen.width into a distance in world space, which I can use to determine the necessary radius at runtime? Is there a better alternative way of doing this?
You can just multiply the orthographic size with the aspect ratio to get the horizontal size:
var orthographicWidth = cam.orthographicSize * cam.aspect;
Of course, whenever your orthographic size changes, you need to update your radius. But that is always the case, even if you convert Screen.width to world space units, this conversion also implicitly depends on the orthographic size and would need to be updated.
Had a need for this functionality and my initial attempt used the logic above (thanks both) but…
On my setup (2D ortho, 54 ppu) I noticed that the logic introduced some rounding errors along the way. Only very small but enough that it resulted in a pixel overdraw.
After some experimenting I found that using the viewport resulted in no rounding errors, so ended up creating these two extension methods…
This one gets the screen rect (zero offset)…
public static Rect GetScreenRect(this Camera value)
{
Vector3 topRight = value.ViewportToWorldPoint(new Vector3(1f, 1f, 0f));
return (new Rect(0f, 0f, topRight.x * 2f, topRight.y * 2f));
}
And this the screen rect in world space…
public static Rect GetScreenWorldRect(this Camera value)
{
Vector3 bottomLeft = value.ViewportToWorldPoint(new Vector3(0f, 0f, 0f));
Vector3 topRight = value.ViewportToWorldPoint(new Vector3(1f, 1f, 0f));
return (new Rect(bottomLeft.x, bottomLeft.y, topRight.x * 2f, topRight.y * 2f));
}
Not sure about the names and hot off the press (that is, only tested\confirmed under my setup) but thought some might find it useful if you hit the same issue.