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

Instantiate/Destroy VS. Enable/Disable

Discussion in 'Scripting' started by soft_limits_dev, Jan 6, 2015.

  1. soft_limits_dev

    soft_limits_dev

    Joined:
    Feb 5, 2014
    Posts:
    8
    Hello,

    I'm testing hardware by creating these massive test scenes with many rigid body game objects. Obviously after a certain point performance degrades. And I know I can adjust the camera clipping planes to improve performance, but I'm wondering if I need something more sophisticated for loading part of a scene, that way I can create an open world game.

    Are there any assets for this?

    Also, I have ideas for loading game objects based on their proximity to the player, and unloading game objects which are far away and off screen.

    Question is, for an open world game where lots of game objects will be in scene, and will be loaded /unloaded pretty often, would it be better to simply enable/disable game objects or to add/remove from memory?

    I realize to answer this question experimentation is needed. But this seems like a common enough problem( partial scene loading) so what kind of strategies have the Unity vets come up with?
     
  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    The technique you are describing is called 'Object pooling' and theres a lot of material on the subject out there.
     
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,377
    There's pros and cons to both.

    In simple terms...

    Instantiate/Destory:
    pro - easy to implement, keeps memory usage to only that what is needed (great for low memory systems)
    cons - expensive to perform, dogs down garbage collection

    Enable/Disable:
    pro - fast on the processor, does not incur expensive garbage collector calls
    cons - complicated to implement, can fill up memory if objects are complex (bad for low memory systems), can result in bugs if the state from previous time enabled isn't reset properly


    Personally what I implemented both into one system in my 'com.spacepuppy.Spawn' namespace of my framework. In it the primary facade is the 'SpawnPool'.

    SpawnPool is a multiton factory (a multiton is like a singleton that can have more than one instance. There is a default global instance, as well as secondary instances that can be used if the default one is to be overriden).

    The SpawnPool maintains prefabs that can be cached for reuse. The SpawnPool has a design time manager that you add prefabs to declaring them cacheable. When you do this you can select metrics for their caching:

    quantity to cache on load
    buffer quantity to load if the cache runs dry
    max quantity allowed to be cached in total

    A profile can even be made that allow varying quantities depending on user system specs. Low memory system, no caching. High memory system, more caching.

    If a prefab is called to be spawned that is not part of the SpawnPool, then it just Instantiates it. This way all code just needs to call 'SpawnPool.Spawn(...)' and the SpawnPool takes care of the rest... making it a replacement for 'Instantiate'.

    There is also a function called 'Kill' that handles destroying gameobjects which replaces the 'Object.Destroy' function. It will determine if the GameObject is a cached object and replace it into the cache pool. Otherwise call Destroy like normal.


    This way I can write code for any project, use the SpawnPool, and if I want to turn off caching... I just go into the SpawnPool manager and turn it off. But all the code still gets performed the same way.
     
  4. soft_limits_dev

    soft_limits_dev

    Joined:
    Feb 5, 2014
    Posts:
    8
    Thanks for the great responses.

    lordofduct,


    Thank you for pointing me in the right direction!
     
    Last edited: Jan 7, 2015
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,377
    duct, like duct tape:

    circa 1997
     
    Last edited: Jan 7, 2015
  6. Juice-Tin

    Juice-Tin

    Joined:
    Jul 22, 2012
    Posts:
    230
    Just wanted to add, Instantiating objects requires you to position them properly. Can be a pain if you have detailed scenes with many objects being created. Much easier to have the scene already layed out and just hit the "on/off" switch. ;)
     
    MaximumTre likes this.
  7. Gua

    Gua

    Joined:
    Oct 29, 2012
    Posts:
    455
    In terms of garbage collection. For example I have torch that checks on a first frame of the game if it is raining and if it's not I want to have a gameobject with fire particles on it.

    For garbage collection, is it better to create object that I need (spawn on torch fire if its not raining), or destroy object I don't need (destroy fire object on torch if it's raining)?
     
  8. Max_Bol

    Max_Bol

    Joined:
    May 12, 2014
    Posts:
    168
    From what I have tested and done myself, one of the best approach to that is actually a mix of 3 things:
    1) Use a proper LOD + Occlusion Culling to make sure unseen torches are disabled.
    2) For each torch, instead of disabling/enabling or destroying/instantiating the particle effect, just change its particle spawn rate to 0. This saves you from filling up the Garbage Collector with the particle effect caches and a particle system with 0 uses barely any resources and can still make use of GPU Instantiating if you properly set each effect to use the same GPU cached mesh + material + textures. It also allows you to have a better transition between the 2 states of the torches (so that the fire doesn't just disappear, but instead have it current live particle dies properly.)
    3) Make sure each identical torches are Batched together. (So, the torches themselves are batched while the particle effects are GPU instantiated.)

    Another possibility, if you want the most efficient results is to set a maximum of torches and, instead of instantiating them or enabling/disabling them, you use a spacial emplacement management script that will move torches around based on your location. This is actually extremely efficient on mobiles as you can just check the distance between the player and each torch position by simple maths and detect the closest torches position to said player and place each torches at those particular position. (To avoid having the torches' fire spawn in-between their position when moved, you got to set the particles system to spawn the particles in local space or to forcefully reset the particle system once moved, which destroy its spawned particles that might by laying around and set it at time 0.)