Search Unity

Does calling GameObject.SetActive(false) increase performance?

Discussion in 'Scripting' started by LostRelicGames, Jul 29, 2014.

  1. LostRelicGames

    LostRelicGames

    Joined:
    Aug 11, 2013
    Posts:
    34
    Hello, I am building a tile based 2D platformer.

    The entire level is laid out in the editor - then at run-time I am detecting if tiles are within the orthographic camera's bounds.

    When a tile is inside or outside of the camera bounds, I am settings its gameObject.setActive to true and false respectively. (objects are invisible until they are within the camera bounds).

    Does doing so gave any positive impact on performance? I can't visibly notice any and am wondering if its worth my while.
    I have also tried setting the tiles 'enabled' to true/false as well as setActive. Is this a good idea?

    Is my approach correct, if not what is the recommended approach?
     
  2. CodeMonke234

    CodeMonke234

    Joined:
    Oct 13, 2010
    Posts:
    181
    Unity already does frustum culling for you -
     
  3. CodeMonke234

    CodeMonke234

    Joined:
    Oct 13, 2010
    Posts:
    181
    It's pretty cool to actually visualize this if you have pro - enable occlusion culling, and you can see them being culled. Frustum culling does not require pro
     
  4. MakeCodeNow

    MakeCodeNow

    Joined:
    Feb 14, 2014
    Posts:
    1,246
    Frustum and occlusion culling save render time but setactive false disables all scripts and physics, too, so it can save much more CPU. Just make sure not to introduce spikes and handle the case where players move back and forth while an object is right on the edge of the screen.
     
  5. LostRelicGames

    LostRelicGames

    Joined:
    Aug 11, 2013
    Posts:
    34
    You explained it well.
    So my understanding is that the default Frustrum culling simply removes the renderer, but does not stop animations or scrips from executing.

    My game is an endless platform runner, so the player cant go backwards, I believe this may be a good scenario to use the setActive(false/true)

    Does setActive also change the 'enabled' flag?

    Code (CSharp):
    1. void OnBecameInvisible()
    2. {
    3. gameObject.setActive(false);
    4. enabled = false ;//  is this needed?
    5. }
     
  6. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    This comment is regarding components that have a mesh renderer attached, nothing to do with behaviours or physics, which are covered above:

    Frustum culling isn't free. At some point, there's too much and it will slow down. You can see how long Unity takes over it by looking at culling in the profiler. On some titles, it's gone up to 100ms - thats incredibly slow. On mobile, the problem magnifies. If you can cull manually, ie a 2D or 3D array of populated cells you can hide things with... then do so.

    Using OnBecameInvisible etc depends on frustum culling, and isn't what I'm referring to which is manual culling.
     
  7. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Why disable things? Remove them, or return them to a pool to be re-used.

    What you're saying implies that as you run infinitely in one direction, you're essentially leaving behind a trail of disabled GameObjects in your wake. This is a bad idea even if they're turned off, because they still exist in the scene and they still use memory, etc.
     
  8. LostRelicGames

    LostRelicGames

    Joined:
    Aug 11, 2013
    Posts:
    34
    Hi Hippocoder,
    Are you recommending to manually cull if there are large amounts of game objects? (In my case 2D tiles, of which there are about 200 per scene).

    If so what is the best way to override the default culling behavior?

    Though i mentioned 'OnBecameInvisible' above in my code example, I am actually manually checking if objects need to be deactivated with a coroutine, that checks the objects x,y,z pos of tiles in relation to the Camera.
     
  9. LostRelicGames

    LostRelicGames

    Joined:
    Aug 11, 2013
    Posts:
    34
    I am not currently procedurally adding/positioning tiles, rather they are pre-positioned in the editor. I'm simply trying to optimize that approach without removing objects completely and pooling them (there also may be circumstances where the player is pushed backwards).

    Regarding items being deactivated and still being left in memory; how much is too much here? As mentioned i'm using about 200 tiles with nothing more then a box collider attached.

    Thanks for the adivce
     
  10. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    It really depends on your target platform. If you can run the whole level as is then it's not too much. It's just that you said it was infinite runner, and they generally involve procedural generating or constructing the level as you go. Since that could theoretically go on forever... well, I'm sure you see where the issue would come from. If you're not adding new stuff as you go I wouldn't worry about it.
     
  11. LostRelicGames

    LostRelicGames

    Joined:
    Aug 11, 2013
    Posts:
    34
    I misdescribed, its a 'constant' runner with a finite level, not infinite in that sense.
    Nice info, ty
     
  12. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    In that case I'd say you're cool. The best way to see if manual culling helps in a meaningful way is to give it a shot on your target platform.
     
  13. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Manual culling might not help much with a strictly 2D title, but like penguin says, its worth looking into. Don't focus too heavily on it, and check the profiler carefully.
     
  14. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Though also, I personally wouldn't worry about this kind of optimisation at all unless I was actually having a performance problem.