Search Unity

How to QUICKLY disable a GameObject?

Discussion in 'Scripting' started by ale870, May 6, 2012.

  1. ale870

    ale870

    Joined:
    Apr 21, 2009
    Posts:
    149
    Hello,
    I made a chunked scenario, and I need to disable a gameobject (which is a kind of "container" - parent for other sub-objects).
    When the player is far away, I want to disable it so Unity does not "scan" it to check if inside the frustum.
    I need this feature since:
    1) I create the scenario at runtime
    2) This gameobject (it is like a sector container, like a box) contains complex sub-objects. So if I use SetActiveRecursively() Unity spend some time and the game temporary freeze.
    3) I need to disable far objects since I have MANY objects in the scenario and, if I add many objects, Unity slows down.

    Is there any way to simply eliminate some objects from the rendering queue (eliminating also collision check and more). I need something like SetActiveRecursively() but it must be FAAAST (can I set a parent to NULL so Unity does not consider that objects (and the children) in the rendering process)?

    thank you !
     
  2. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Make your own method to disable the unnecessary components, instead of the entire Game Objects.
     
  3. ale870

    ale870

    Joined:
    Apr 21, 2009
    Posts:
    149
    I need to disable the gameobject, since that gameobject is like a sector: and I need to disable sectors far away from player, in order to eliminate them from engine computation.
     
  4. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    How much computation is a Game Object with nothing enabled taking up? Personally, I haven't found much use for disabling objects at runtime; I used to need it for colliders, before whatever recent release added the ability to disable them.
     
  5. ale870

    ale870

    Joined:
    Apr 21, 2009
    Posts:
    149
    if I have all objects enabled Unity slows down (while I create them at runtime).
    I want to make another test: how can I disable only colliders in children objects of a main gameobject?

    SECTOR(GameObject) <-- here there is the script to disable colliders in children
    \--child 1(MeshCollider)
    \--child 2(MeshCollider)
     
  6. MadRobot

    MadRobot

    Joined:
    Jul 12, 2011
    Posts:
    339
    There are some methods that may be useful to you. Specifically OnBecameVisible and OnBecameInvisible. Maybe you could do something with those?

    For your other question, try something like this
    Code (csharp):
    1.  
    2. GameObject main;
    3. // assign the 'main game object' to 'main'
    4.  
    5. Collider[] childColliders = main.GetComponentsInChildren<Collider>();
    6.  
    7. for (int i = childColliders.Length ; i > o ; i--)
    8.   childColliders[i-1].enabled = false;
    9.  
     
    Last edited: May 6, 2012
  7. MadRobot

    MadRobot

    Joined:
    Jul 12, 2011
    Posts:
    339
    Disabled scripts still listen for all the OnEvent events. And they still execute that code when disabled. That might be why he wants to disable the entire game object.
     
  8. ale870

    ale870

    Joined:
    Apr 21, 2009
    Posts:
    149
    Yes, that's true. In fact, unity engine processes objects even if not visible, not rendered, etc... If yo have a lot of objects in the scene, you need to disable them, or the engine will go slower and slower since it has to process all the models (even if far away, even if not visible).

    I wish a method like a DUMMY-parenting (in order to eliminate some objects from the engine process).
    Now I'm testing if disable collisions is enough (I hope but...).
     
  9. ale870

    ale870

    Joined:
    Apr 21, 2009
    Posts:
    149
    UPDATE: disabling colliders does not solve the problem.
    So the issue is this one:
    I need to divide the scenario in sectors: every sector contains several static models. I need to enable/disable sectors QUICKLY (without the player may notice a lag). I cannot find a way to achive this.
    I need to disable objects/sectors since unity with many models slows down, even if those objects are not visible.
     
  10. Myx

    Myx

    Joined:
    Nov 29, 2010
    Posts:
    196
    Hello there!

    I've been in a similar situation a couple of times, the solution I generally go with is to gather all the game objects in an array and disable each one of them separately. It's basically SetActiveRecursively but you only run the code gathering all the child objects once.

    Code (csharp):
    1.  
    2. private GameObject[] mObjects;
    3. private bool mState = true;
    4.  
    5. void Awake()
    6. {
    7.     // All GameObjects must have exactly one Transform component, so fetching all transforms
    8.     // will get us an array referencing every game object, including the root object
    9.     Transform[] allObjects = transform.GetComponentsInChildren<Transform>();
    10.    
    11.     // We need the game objects, not the transforms
    12.     mObjects = new GameObject[allObjects.Length];
    13.     for(int i = 0; i < mObjects.Length; i++)
    14.         mObjects[i] = allObjects[i].gameObject;
    15. }
    16.  
    17. public void SetState(bool state)
    18. {
    19.     // Activating and deactivating game objects is costly, so make sure
    20.     // the objects are not already in the required state
    21.     if(mState == state)
    22.         return;
    23.     mState = state;
    24.  
    25.     // Set all objects in the array to the requested state
    26.     for(int i = 0; i < mObjects.Length; i++)
    27.         mObjects[i].active = mState;
    28. }
    29.  
    Note that I wrote this code in browser, so I can't guarantee it's faultless.
    This code assumes that you don't add or remove any objects to the sector in runtime. Should that be the case you'd need to add/remove the relevant objects from the object-array.