The camera is sort of top down and the player can move objects around, rotate them, delete them etc. I use a raycast to check what was hit when the player clicks. But some objects are culled by the LOD group when far away, but the LOD group only disables the renderer, not the colliders, so it still interacts with the raycast. This means a player can move or delete an object that they can't even see.

I've tried looping through all the renderers in the lod group and using renderer.isVisible but it doesn't solve the problem of collision and raycasts. I'd really rather not poll isCulled every frame in update either because there are thousands of gameobjects, that would be horrible for performance.

LODGroup lodGroup = GetComponent<LODGroup>();
LOD[] LODs = lodGroup.GetLODs();
for (int i = 0; i < LODs.Length; i++)
{
    LODRenderers = LODs[i].renderers;
}

bool isCulled = true;

for (int i = 0; i < LODRenderers.Length; i++)
{
    if (LODRenderers[i].isVisible)
    {
        isCulled = false;
    }
}

Use is render visible via transform:

 LODGroup groupLOD = obj.GetComponent<LODGroup>();
 if (lodGroup != null)
 {
     Transform lodTransform = groupLOD.transform;
     foreach (Transform child in lodTransform)
     {
         var renderer = child.GetComponent<Renderer> ();
         if (renderer != null && renderer.isVisible)
         { 
             Debug.Log("current lod is" + child.name); 
         }
     }
 }
  • This doesn't work because some LOD groups are only being used for culling, so there are no child objects, the renderer is on the same object as the LOD group. Therefore, looping through the renderers via the transform doesn't work. – mr-matt Dec 5 at 17:34
  • How about getting the vertices of the current mesh? docs.unity3d.com/ScriptReference/Mesh-vertices.html you could use this and make a switch based on the lod vertices count and then enable/disable whatever you need to. – Prometheus Dec 5 at 18:18
  • What will that achieve? – mr-matt Dec 5 at 18:19
  • Actually, I realised checking if its culled isn't the entire problem, I've updated the question. – mr-matt Dec 5 at 18:26
  • Glad you could fix it. – Prometheus Dec 6 at 6:52
up vote 0 down vote accepted

Solved over here: https://forum.unity.com/threads/lod-culled-gameobject-still-interacts-with-raycast.593410/

Basically RaycastAll or RaycastNonAlloc is used because they do not stop the raycast when a object is found, they return all the objects in the path of the raycast. I then sort them by distance, checking that they are visible at the same time.

I'll copy the code here for convenience.

float minDist = Mathf.Infinity;
int minDistIndex = -1;

for (int i = 0; i < m_RaycastHits.Length; i++)
{
    if (m_RaycastHits[i].collider == null)
        continue;

    if (m_RaycastHits[i].distance < minDist)
    {
        Element element = m_RaycastHits[i].collider.GetComponent<Element>();

         if (element.IsCulled)
             continue;

         minDist = m_RaycastHits[i].distance;
         minDistIndex = i;
    }
}

if(minDistIndex != -1)
{
    //do something with m_RaycastHits[minDistIndex]
}

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.