Lobsang White
Lobsang White

Reputation: 107

Check if the object is off screen

I need to know when an object has stopped seen by the camera to return it to the pool. I tried a couple things but not success, I want to remark the camera follow the player only in the X axis, it's 3D but it's a sidescroll view game. Btw I'm not using MonoBehaviour so avoid suggest OnBecameInvisible and relatives.

Here my two failed attempts.

internal static bool IsVisible(this Renderer renderer)
{
    Plane[] planes = GeometryUtility.CalculateFrustumPlanes(Camera.main);
    return GeometryUtility.TestPlanesAABB(planes, renderer.bounds);
}

internal static void IsVisible(this GameObject go)
{
    var screenPoint = Camera.main.WorldToScreenPoint(go.transform.position);
    screenPoint.x = Mathf.Clamp01(screenPoint.x);

    if (screenPoint.x > .05f)
    {
        Debug.Log("Visible");
    }
    else Debug.Log("Invisible");
}

Upvotes: 3

Views: 13854

Answers (3)

Will
Will

Reputation: 11

var pos = Camera.main.WorldToScreenPoint(transform.position);
        if (pos.x > (Screen.safeArea.xMax))
        {
            Vector3 newpos = new Vector3(Screen.safeArea.xMin, pos.y, pos.z);
            transform.position = new Vector3(Camera.main.ScreenToWorldPoint(newpos).x, transform.position.y, transform.position.z);
        }
        if (pos.x < Screen.safeArea.xMin)
        {
            Vector3 newpos = new Vector3(Screen.safeArea.xMax, pos.y, pos.z);
            transform.position = new Vector3(Camera.main.ScreenToWorldPoint(newpos).x, transform.position.y, transform.position.z);
        }
        if (pos.y > Screen.safeArea.yMax)
        {
            Vector3 newpos = new Vector3(pos.x, Screen.safeArea.yMin, pos.z);
            transform.position = new Vector3(transform.position.x, Camera.main.ScreenToWorldPoint(newpos).y, transform.position.z);
        }
        if (pos.y < Screen.safeArea.yMin)
        {
            Vector3 newpos = new Vector3(pos.x, Screen.safeArea.yMax, pos.z);
            transform.position = new Vector3(transform.position.x, Camera.main.ScreenToWorldPoint(newpos).y, transform.position.z);
        }

Upvotes: 1

zambari
zambari

Reputation: 5035

If you need to know when you object moves in and out of screen, the simplest soluton is MonoBehaviour.OnBecameVisible() paired with .OnBecameInvisible()

Edit: okay, I just read that you are not using MonoBehaviours - may I ask why? Monohevaiours only cost for methods you actually implement, there isn't that much overhead from just inheriting from MonoBehaviour

Upvotes: 1

user10976548
user10976548

Reputation:

Simple:

if(!GetComponent<Renderer>().isVisible){
//Whatever you want to do here
}

If you are having trouble, see:

https://docs.unity3d.com/ScriptReference/Renderer-isVisible.html

https://forum.unity.com/threads/how-do-i-use-renderer-isvisible.377388/

Upvotes: 3

Related Questions