Reputation: 49
I am using c# in unity and I need to calculate the lowest y position of the camera (2D) however I only know how to find the height i.e.
private Vector2 screenBounds;
void Start()
{
screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
}
void Update()
{
screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
if (transform.position.y < screenBounds.y)
Destroy(this.gameObject);
}
}
I am trying to use this code to despawn old objects.
Upvotes: 2
Views: 2782
Reputation: 90683
What you get is the top-right corner
Screenspace is defined in pixels. The bottom-left of the screen is (0,0); the right-top is (pixelWidth,pixelHeight).
Also I assume your camera position is e.g. z = -10
and you want a world point in front and not behind the camera
So if you want the bottom border you would rather use
screenBounds = Camera.main.ScreenToWorldPoint(new Vector3 (0, 0, -Camera.main.transform.position.z);
If your camera is orthogonal anyway then you don't have to care about the z
at all and can just use
screenBounds = Camera.main.ScreenToWorldPoint(Vector2.zero);
In order to not have to calculate twice if you also want to check later if it is above the screen you could also go the other way round though which is often even easier:
// Other than the ScreenToWorldPoint here it doesn't matter whether
// the camera is orthogonal or perspective or how far in front of the camera you want a position
// or if your camera is moved or rotated
var screenPos = Camera.main.WorldToScreenPoint(transform.position);
if(screenPos.y < 0) Debug.Log("Below screen");
else if(screenPos.y > Screen.height) Debug.Log("Above screen");
if(screenPos.x < 0) Debug.Log("Left of screen");
else if(screenPos.x > Screen.width) Debug.Log("Right of screen");
However, using only the transform.position
is a bit unreliable since you already would destroy objects that are still (half) visible.
Instead you could use GeometryUtility.CalculateFrustumPlanes
to get the planes surrounding the actual camera frustum and then use GeometryUtility.TestPlanesAABB
to check wether your objects' Renderer.bounds
are actually visible to the camera like e.g.
Renderer _renderer;
Camera _camera;
void Update()
{
if(!_renderer) _renderer = GetComponent<Renderer>();
if(!_camera) _camera = Camera.main;
var planes = GeometryUtility.CalculateFrustumPlanes(_camera);
if (!GeometryUtility.TestPlanesAABB(planes, _renderer.bounds))
{
Debug.Log($"\"{name}\" is outside of the screen!", this);
// and e.g.
Destroy(gameObject);
}
}
Upvotes: 2
Reputation: 2598
If I understand correctly you want to save the initial box the camera sees and use that as a boundary?
If that's the case then it's easy to do in 2D, but gets much more complex in 3D. So below is the 2D solution.
The camera is in the center of the viewport. Meaning that the top boundry is the Camera position plus half the height of the viewport.
// Get the camera height
float height = Screen.height;
// Now we get the position of the camera
float camY = Camera.Main.transform.position.y;
// Now Calculate the bounds
float lowerBound = camY + height / 2f;
float upperBound = camY - height / 2f;
Upvotes: 0