1
\$\begingroup\$

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;
    }
}
\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

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); 
         }
     }
 }
\$\endgroup\$
5
  • \$\begingroup\$ 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. \$\endgroup\$
    – mr-matt
    Commented Dec 5, 2018 at 17:34
  • \$\begingroup\$ 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. \$\endgroup\$
    – Prometheus
    Commented Dec 5, 2018 at 18:18
  • \$\begingroup\$ What will that achieve? \$\endgroup\$
    – mr-matt
    Commented Dec 5, 2018 at 18:19
  • \$\begingroup\$ Actually, I realised checking if its culled isn't the entire problem, I've updated the question. \$\endgroup\$
    – mr-matt
    Commented Dec 5, 2018 at 18:26
  • \$\begingroup\$ Glad you could fix it. \$\endgroup\$
    – Prometheus
    Commented Dec 6, 2018 at 6:52
0
\$\begingroup\$

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]
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .