OnBecameVisible / OnBecameInvisible run in editor despite no cameras being on it

Yes, I know about the Scene camera quirk.

There seems to be some sort of issue in Unity 2018.4.31 that I just discovered. I have my GameObjects set up so that their script components do not activate until they are visible to a camera.

When I start up my scene, there is a quick blip where they are visible and then not visible again. I took care in facing the Scene camera away from everything. I even closed the window entirely, and disabled every camera. However, a handful of game objects are still having this blip. Here’s the code I’m using:

public class EnemyActivatorForRenderer : MonoBehaviour
    {

        public void OnBecameVisible()
        {
            EnemyActivator ea = gameObject.GetComponentInParent<EnemyActivator>();
            if (ea != null)
            {
                Debug.Log(transform.parent.gameObject.name+" <color=blue>is visible!</color>");
                ea.OnBecameVisible();
            }
        }

        public void OnBecameInvisible()
        {
            EnemyActivator ea = gameObject.GetComponentInParent<EnemyActivator>();
            if (ea != null)
            {
                Debug.Log(transform.parent.gameObject.name+" <color=blue>is NOT visible</color>");
                ea.OnBecameInvisible();
            }
        }
    }

I’ll see if I can create a bug report, but does anyone know a workaround? What I need is for my scripts to not run until the player can actually see them.

Does your game object have a renderer, or is the renderer sitting on the parent?

"OnBecameVisible is called when the renderer became visible by any camera.
This message is sent to all scripts attached to the renderer."

1 Like

You could try to adding Debug.Log(Camera.current), to check if any camera is in fact rendering. Camera.current should be the camera in context for those function. Reflection probes also use a camera, so it’s possible they are triggering the functions.

1 Like

The renderer is on the gameObject, which calls a script also called OnBecameVisible() that I implemented on the parent object. This is because the visual model is (in most cases) a child of my gameObject which just has the behaviors, colliders, and what have you.

This is it. I added that and got this back:

Mask Camera (UnityEngine.Camera)
UnityEngine.Debug:Log(Object)
VisionBreak.Sunsear.EnemyCore.EnemyActivatorForRenderer:OnBecameVisible() (at Assets/Sunsear/Scripts/EnemyActivatorForRenderer.cs:15)

I have no idea what a “Mask Camera” is, but I guess Unity’s functionality is vindicated here. There shouldn’t be any reflection probes being used since this is a mobile game, but there’s clearly something unexpected going on.

Thanks for your responses! Any idea what could be creating that phantom camera object?

Mask Camera could be from a third-party asset, using a hidden camera. The name is pretty specific, so you could do a search for it in your code base.

In your OnBecameVisible function you can do a check on the camera type, to see if it’s an actual “Game” camera, if not, bail out

//Skip for any special use camera's (except scene view camera)
if (camera.cameraType != CameraType.SceneView && (camera.cameraType == CameraType.Reflection ||
                                                  camera.cameraType == CameraType.Preview ||
                                                  camera.hideFlags != HideFlags.None)) return;
1 Like

What I decided to do was have a boolean method check for this Mask Camera. I found the source of it (it’s some post-processing stuff), and having the OnBecameVisible functions bail on all non-game cameras was giving it problems. I now know how to find the other hidden cameras so if they start causing problems I can filter them one at a time.

public bool IsInvalidCamera(Camera camera) {
            if (camera == null) return true;
            return camera.cameraType != CameraType.SceneView 
                && (camera.name == INVALID_MASK_CAMERA);
        }

Thanks so much for your help! :smile: