- Home /
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?
Answer by twobob · Apr 15, 2017 at 03:57 AM
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
an obvious improvement would be to take a a copy of the 'vis' value and simply do a compare to not keep triggering the events needlessly when no change has occurred.
Another would be to find a way to attach to the existent OnVisibilty methods of the correct subrenderer from this scrip based on deriving the taxonomy (via a similar method to this - or this - first) - that seems doable but beyond my knowledge.
Answer by JimPD · Sep 12, 2017 at 10:48 AM
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;
}
}
Your answer
Follow this Question
Related Questions
Terrain Trees LOD working in reverse 1 Answer
Implement a LOD System similar to the Unity LOD 0 Answers
Search and remove LODs from LODGroup through script 0 Answers
Creating LOD Group for character 4 Answers
Terrain LOD? 1 Answer