Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Get all meshes in an area... without colliders.

Discussion in 'Scripting' started by naked_chicken, Jun 11, 2014.

  1. naked_chicken

    naked_chicken

    Joined:
    Sep 10, 2012
    Posts:
    186
    So I have a script that, whenever it is instantiated, needs to grab all meshes within its object's bounds and iterate over all of them.

    Originally I used:

    Code (csharp):
    1. Collider[] colliders = Physics.OverlapSphere(transform.position, _myRadius);
    2. for (int i = 0; i < colliders.Length; i++)
    3. {
    4.     MeshFilter filter = colliders[i].GetComponent<MeshFilter>();
    5.     if(filter != null)
    6.     {
    7.         //Do Stuff.
    8.     }
    9. }
    Which was happy and fast but required that every object had to have a collider on it. Turns out this wasn't possible so I had to switch to:

    Code (csharp):
    1. MeshFilter[] filters = FindObjectsOfType<MeshFilter>();
    2. for (int i = 0; i < filters.Length; i++)
    3. {
    4.     MeshFilter filter = filters[i];
    5.    
    6.     if (filter.renderer.bounds.Intersects(_myBounds))
    7.     {
    8.         //Do Stuff
    9.     }
    10. }
    This, as you might imagine, is not so fast. With the sheer number of objects in our scenes, it's actually unacceptably slow.

    So my question, has anyone found any fast ways of gathering all meshes within an area that does not require colliders?
     
  2. Fluzing

    Fluzing

    Joined:
    Apr 5, 2013
    Posts:
    815
    The only way I know how to do that is to go through all of the gameobjects in the scene and calculate the distance from the object. Doubt that is faster though.

    " Which was happy and fast but required that every object had to have a collider on it. Turns out this wasn't possible so I had to switch to: "

    Why wasnt this possible?
     
  3. naked_chicken

    naked_chicken

    Joined:
    Sep 10, 2012
    Posts:
    186
    Just the way the artists had set up their levels. I came in on the project when it was part way done and going back and changing how collision was done on every object wasn't really an option :(
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    You couldn't use trigger colliders on their own layer?
     
  5. Graham-Dunnett

    Graham-Dunnett

    Unity Technologies

    Joined:
    Jun 2, 2009
    Posts:
    4,287
    Instead of getting the MeshFilter, can't you get the Transforms, and then compute how far it's position is from your position. You don't need to do a square root to get the real length, just see if the square of the distance is greater than your _myRadius squared. This will give you an approximate list of "nearby" objects.
     
  6. naked_chicken

    naked_chicken

    Joined:
    Sep 10, 2012
    Posts:
    186
    The reason I use the MeshFilters is I need to do a bounds check to see if a mesh intersects the bounds of my object. Distance wouldn't work because that's just from the center and there is a wide variance of mesh sizes in the scene.
     
  7. Sharp-Development

    Sharp-Development

    Joined:
    Nov 14, 2013
    Posts:
    353
    Thats acctually what physics is for, to detect exactly that stuff.
    Iterating over all objects is never a good idea, nor good design, no matter what you acctually do with it. Therefore, either add a box collider as bounding box or implement your own logic.

    As of implementing your own logic, you'll have to dive into the game physics world. Create a custom component representing a bounding box and check them via a broadphase algorythm, either Hierarchical hash grid or Sweep and Prune.
     
  8. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    Why is it not possible to have a collider on everything? If you have some which should not collide, set their layer to one which is ignored in the Physics settings
     
  9. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    if you have a bounds, and you iterate through all the active objects in the scene, you can then figure if each object has a meshfilter. If it does, compare the meshfilter's bounds to the bounds you are looking at. That would be the "correct" way to do it.

    Bounds to bounds testing is very fast, faster than Vector3.Distance.
     
  10. naked_chicken

    naked_chicken

    Joined:
    Sep 10, 2012
    Posts:
    186
    That's actually what I'm doing. There are a LOT of objects in our scenes however, so its a bit slower than I'd prefer.
     
  11. novashot

    novashot

    Joined:
    Dec 12, 2009
    Posts:
    373
    could have empty objects with a trigger and a list of all objects within that trigger... when your player enters each trigger area it only has to check vs that area's list of objects
     
    chelnok likes this.
  12. naked_chicken

    naked_chicken

    Joined:
    Sep 10, 2012
    Posts:
    186
    hmmm, that's an interesting idea. Could do a pre-bake like the Occlusion bake.