OnBecameVisible and OnBecameInvisible with LOD group.

I am wishing to use OnBecameVisible and OnBecameInvisible for some gameobjects. For ordinary objects with a mesh renderer, my script works fine. But for objects with a LOD group, these functions doesn’t get called on the parent object. It only works if script is added for child gameobjects (i.e. *_LOD1 gameobject).

This causes wrong calls of OnBecameVisible/OnBecameInvisible when lod group switches between lod groups.

Is there a better way to understand that a gameobject with lod group is or isn’t visible on screen?

Setup some refs

	private Transform PolledForVisibilty;

	private Renderer RendererPolledForVisibilty;

    public float TEST_PERIOD = .3f;

Shove some stuff in start

if (gameObject.GetComponent<LODGroup>() != null) {

			PolledForVisibilty = gameObject.GetComponent<LODGroup> ().transform;
			InvokeRepeating ("SlowlyPollTheVisibilityOfLOD", 1f, TEST_PERIOD);

		} else
		
			if (gameObject.GetComponent<SkinnedMeshRenderer>() != null) {

			// Do nothing. We handle this with OnBecomeVisible etc.
			
			} else
		{

			RendererPolledForVisibilty = gameObject.transform.GetComponentInChildren<Renderer> ();  
		        InvokeRepeating ("SlowlyPollTheVisibilityOfSingleRenderer", 1f, TEST_PERIOD);
		}

and they call in the main body

	void OnBecameInvisible()
	{
		//Debug.Log (gameObject.name + " invisible");
	}
	void OnBecameVisible()
	{  
		//Debug.Log (gameObject.name + " visible");
	}

via the invokes

	void SlowlyPollTheVisibilityOfLOD()
	{
		bool vis = false;

		foreach (Transform child in PolledForVisibilty)
			{
				var renderer = child.GetComponent<Renderer> ();
				if (renderer != null && renderer.isVisible)
				{ 
					vis = true;
				}
			}

			if (vis) {OnBecameVisible ();} else {OnBecameInvisible ();}

	}


	void SlowlyPollTheVisibilityOfSingleRenderer()
	{

		bool vis = false;  

		if (RendererPolledForVisibilty != null && RendererPolledForVisibilty.isVisible)
			{ 
				vis = true;
			}
  
		if (vis) {OnBecameVisible ();} else {OnBecameInvisible ();}

	}

Tweak period of .3f to your needs.
I came up with that mess to get around the various possible things I might end up attaching this to.

Seems to work fine. Hope it helps

Don’t do the above. You can get individual renderers from an array

/// <summary>
    /// Determines if a renderer that is part of a LOD Group is visible, if so place UI object over it
    /// </summary>
    /// <param name="UIObject"></param>
    /// <param name="_gameObject"></param>
    public void UIFollowGameObject(RectTransform UIObject, GameObject _gameObject)
    {
        // Get LOD Group on your gameObject
        LODGroup lodGroup = _gameObject.transform.root.GetComponent<LODGroup>();
        // If the GameObject has a LODGroup
        if (lodGroup != null)
        {
            // Get an array of LODS from that group
            LOD[] _lods = lodGroup.GetLODs();
            // If the LODGroup has LODS
            if (_lods != null)
            {
                // Get the first Renderer within that LOD group
                Renderer _lodRenderer = _lods[0].renderers[0];
                // if the LOD has a renderer
                if (_lodRenderer != null)
                {
                    if (_lodRenderer.isVisible)
                    {
                        // The renderer is visible
                        // I set a UI element to be placed over the top of it
                        Vector3 screenPoint = RectTransformUtility.WorldToScreenPoint(player.GetComponent<Camera>(), _gameObject.transform.position);
                        UIObject.gameObject.SetActive(true);
                        UIObject.position = screenPoint;
                    }
                    else
                    {
                        // The renderer is not visible 
                        UIObject.gameObject.SetActive(false);
                        return;
                    }
                }
                else
                {
                    // The LOD Does not has a renderer assigned
                    return;
                }
            }
            else
            {
                // The LOD Group has not had any LODs assigned
                return;
            }
        }
        else
        {
            // The GameObject hasnt a LOD Group assigned
            return;
        }
    }