Search Unity

How to pool object?

Discussion in 'Scripting' started by Shayke, Jul 10, 2018.

  1. Shayke

    Shayke

    Joined:
    Dec 8, 2017
    Posts:
    352
    Hey, i just started an endless runner game and im using a pool for coins for instance.
    But i wonder how to use other things like effects.
    When i take a coin i want to instantiate an effect and destroy it afterward.
    What i did so far is to make a pool for the specific effect too but i don't know if it is the right way because i need like 10 effects. Should i use 100 unactive gameobjects??
    If someone could make things clear for me i would appreciate.
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
  3. FMark92

    FMark92

    Joined:
    May 18, 2017
    Posts:
    1,243
    I use a modified version of Quill18's Simple Pool. Google that, source code is freely available.
     
  4. Shayke

    Shayke

    Joined:
    Dec 8, 2017
    Posts:
    352
    I am not a fan of other people's codes, i get struggled to read it and understand.
    I rather understand the idea behind it and make it on my own.
    But i'll take a look, thanks guys.
     
  5. duisti

    duisti

    Joined:
    Nov 29, 2017
    Posts:
    52
    Yes, each effect should have its own pool. The size should be the one you *think* how many of those said effects can be active at once, plus a few on top of that just in case of errors. In case of pooling sound effects, there you could have a generic sound GameObject where you just swap to a different sound clip when you play it. And of course here you need to have a bigger buffer size. Pretty much how max sound channels work.
     
  6. newjerseyrunner

    newjerseyrunner

    Joined:
    Jul 20, 2017
    Posts:
    966
    Pools aren't that difficult to create, I have a variety of types of them in my code base.

    The way mine works is that the pool creates X number of items in an array on startup. Then allows each of those gameobjects to run their Start routine. I then use SetActive(false) to put the object to sleep until I need it.

    My pool itself has an iterator that knows where the last returned object was in the array. Every time I call "get," I check the gameObject at position array[iterator]. If this object is not active, I increment the iterator (and loop around if needed) then return the object. If the object is active, then I will move the iterator until I either find an inactive one, or have gone through the whole list, in which case I will return the original (it's a safe assumption that it's the oldest.)
     
  7. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,037
    Two lists of objects in and out of use should do the trick if you want it simple. You probably know how many effects can play at once. That's your starting unused pool size. Take one out, move it to the active list, create a larger list if it ever runs out, log that and set the maximum you come across as your default size for the finished product.
     
  8. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,092
    What kind of effects? can't you use the particle system for those effects?
    Else each effect should have its own pool. For a pool script I would just create something that contains a list of objects and create a method for Getting from the pool / Returning it to the pool. If the pool is out of objects while getting -> instantiate another clone. Done with the object? return it to the pool and set it inactive. it ain't that difficult to create.
     
  9. FMark92

    FMark92

    Joined:
    May 18, 2017
    Posts:
    1,243
    Quill documents his code very well though.
     
  10. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    I created a polling pool base class that I can derive from, which makes it convenient for stuff like particles, my particle pool looks like this

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace Assets.Scripts.Utils
    4. {
    5.     public class ParticleSystemPool : PollingPool<ParticleSystem>
    6.     {
    7.         public ParticleSystemPool(ParticleSystem prefab) : base(prefab)
    8.         {
    9.         }
    10.  
    11.         protected override bool IsActive(ParticleSystem component)
    12.         {
    13.             return component.isEmitting;
    14.         }
    15.  
    16.         public void StartAt(Vector3 point, Quaternion rotation)
    17.         {
    18.             var system = Get();
    19.  
    20.             system.transform.position = point;
    21.             system.transform.rotation = rotation;
    22.         }
    23.     }
    24. }
     
  11. Shayke

    Shayke

    Joined:
    Dec 8, 2017
    Posts:
    352
    So after reading some comments i tryed to do something.
    Basically what i did was a List with approximately the number of items i want to reuse and initially instantiate them.
    When i need to use the object i check if i have an object not active and i use it. if everyone is active(check by counter), i resize the List and instantiate a new one.

    And another thing that i don't understand:
    I started to work with pools because my game started to work slow and i figured the GC thing.
    But when i see my first game, i shot thousands of bullets (instantiate and destroy) and the game works totally fine and nothing become slower.
    No idea why, someone can explain?
     
  12. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,092
    if depends on how much garbage is generated and whether you collect that garbage manually frequently or automagically. The garbage collecting causes lag spikes. In my opinion garbage generation should be avoided as much as possible especially if it is something happening frequently.
    If you're uncertain as to why your game is slow, use the Unity profiler. The tools are there to show you what is taking your time.
     
  13. newjerseyrunner

    newjerseyrunner

    Joined:
    Jul 20, 2017
    Posts:
    966
    Depending on the type of object in the pool, you may want to not instantiate a new one and simply reuse the instance that’s the oldest.

    Although some of my pools do expand like that, for most of them I’d rather an old item simply vanish than create more. Mostly because I’ve tuned the performance around a fixed number of object. I do this for things like blood splatter and particle effects.
     
  14. Shayke

    Shayke

    Joined:
    Dec 8, 2017
    Posts:
    352
    I am comfused right now.
    My way is the right one? Instantiate new one and reuse them too?
    Or should i reuse just the old one and remove the new one?
     
  15. newjerseyrunner

    newjerseyrunner

    Joined:
    Jul 20, 2017
    Posts:
    966
    Yeah, your way is right. I was just mentioning that you may want to cap the number eventually.
     
  16. Shayke

    Shayke

    Joined:
    Dec 8, 2017
    Posts:
    352
    Ok.
    Thanks my friend, helped me alot.