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

Object Pooling: To instantiate, or not to instantiate

Discussion in 'Scripting' started by Mikenseer, Jan 7, 2015.

  1. Mikenseer

    Mikenseer

    Joined:
    Jul 24, 2012
    Posts:
    72
    The question is, in a case when object pooling is being used (from game start for arguments sake), is it better/worse to:

    A. Start with 0 objects, loop through an "ObjectPool" function to instantiate a variable number of prefab (clone)objects.

    B. Start with the max # of objects to avoid instantiating all together.

    My guess is each has their advantages/disadvantages depending on the use case. Feel free to elaborate.

    A more specific question is does either method allow more scripting access, or is it the same besides initial communication (i.e. objects in the explorer can be drag and dropped into scripts, while instantiated clones may need to be "found" through script perhaps)?

    Perhaps this is a silly question but I thought it would be fun to ask. FYI: Object Pooling
     
  2. Graham-Dunnett

    Graham-Dunnett

    Unity Technologies

    Joined:
    Jun 2, 2009
    Posts:
    4,287
    I'd do B. It's never occurred to me that A is object pooling.
     
  3. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    We do both....sort of. For effects, the pool checks if it has an unused one available and instantiates if it doesn't; the idea being that you'll eventually reach a threshold where you don't need to instantiate anymore. For stuff that we know we'll need a lot of (like unit selection indicators) we create a set number of them initially. The pool still does the same checks and instantiates new ones up to a max number; we just shortcut some of the overhead that we know we'll need immediately.
     
    Mycroft likes this.
  4. Juice-Tin

    Juice-Tin

    Joined:
    Jul 22, 2012
    Posts:
    230
    I would say B.

    With A, you need to do a lot of manual work to drag in all the objects, which will be instantiated when unity runs anyway.

    With B, you dynamically create them all at the start, but this way you can easily adjust the size of the pool later on, or create pools for other things just as easily without having to manually drag 200 objects in through inspector every time.
     
  5. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    I use the same pattern as Kelso.

    Start with none, object gets requested, if there's one in the pool, use it, if not create new one. Ensures there will always be an object to use if you arnt sure how many you will actually need. My pools only hold objects that arn't in use.
     
  6. Zaladur

    Zaladur

    Joined:
    Oct 20, 2012
    Posts:
    392
    This, though I don't start with zero. I'll start with a small number that I know is likely to be exhausted, though not necessarily. A few more up front instantiations for almost no instantiations during regular gameplay.
     
  7. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Depends on what you're doing. In an RTS, starting with zero can be legit in instances where, for example, two players are playing the same faction and therefore *none* of the effects for the other factions will ever be used.
     
    Mycroft likes this.
  8. Zaladur

    Zaladur

    Joined:
    Oct 20, 2012
    Posts:
    392
    Whoops, maybe I misunderstood. I always start with zero when the play button is hit. But as the scene loads (and say my factions are now chosen), I run through and fill my pools slightly with appropriate objects so that when actual gameplay is happening, the pools have a starting amount of objects to pull from.
     
  9. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    only thing I really pool atm is projectiles.

    being pc based, theres no real need for me to instantiate ahead of time. Theres no heavy lifting done in my instantiates.
     
  10. SevenHams

    SevenHams

    Joined:
    Dec 27, 2012
    Posts:
    67
    Both have their uses, really. The advantage of B is that you can go through the process of creating a bunch of stuff before the game is being played which allows you to do more code while the game is being played. Instantiating isn't free. B is also useful if you know the maximum number of objects you'll actually need. If you're creating and destroying a lot of objects quickly that can needlessly increase overhead. More efficient to just turn objects on and off.
     
  11. Mikenseer

    Mikenseer

    Joined:
    Jul 24, 2012
    Posts:
    72
    This is the theory I meant to capture with A.

    B being you manually place the objects in the explorer and write no scripts that create objects, as you already have the max.

    I think some people may have mis-understood my explanations, which is my bad. No biggy, still solid answers.
     
  12. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    You pay the instantiate cost during scene loading regardless of weather you create the objects in the scene or if you instantiate them via script on loading.

    Back to the OP, it really depends on the application.

    For something like projectiles on a PC, I'd go with approach A. Instantiate the bullets as the player needs them. I'd also consider a regular check to shrink the pool back down if there are objects on it that haven't been used for a while

    On something like an infinite runner on a mobile device I would probably go for B. For mobile games its often possible to calculate the exact number of objects that can fit on the screen. Create this many on start up and no more. I'd also mark them all with DontDestroyOnLoad. The user should only have to deal with the game loading once, not every time he dies and the scene restarts.
     
  13. Mikenseer

    Mikenseer

    Joined:
    Jul 24, 2012
    Posts:
    72
    That is such a simple concept that I totally missed. Thanks for that suggestion. Especially for short simple phone games this makes perfect sense.
     
  14. Eluem

    Eluem

    Joined:
    Apr 13, 2013
    Posts:
    57
    Out of curiosity, when do you feel object pooling is necessary? Should all projectiles always be pooled, even if they're relatively rare. How rare do they need to be to not need object pooling?

    For example, it's clear that you'd want to object pool projectiles from a high rate of fire weapon, like a machine gun. How about a rocket launcher? What about something sort of in between, like a Spinfusor in Tribes?

    I'm not sure when I'm gaining enough to justify the set up and the overhead, heh.

    Another major issue I'm having with object pooling on complex projectiles in unit, is resetting them properly. I'm not sure if there's something fundamental that I'm missing, but the way I'm setting up my poolable objects, there's 4 elements:
    1) The pool itself (I'm just using a simple dictionary of stacks that I can pull from and push into for each object type that can be pooled)

    2) A "DestroyMe" function that hides the object in the inspector and sets active to false, instead of destroying it, if the object is flagged as Pooled

    3) An Initialization function, which basically replaces the constructor. It only initializes things I think shouldn't change, even when the object is respawned. Basic details about the object.

    4) A Spawn function, this will be called every time the object is either created or reused from the pool.


    I'm doing all the resetting in the Spawn function, and it seems logical to me, but there's so much stuff to reset on some of the more complex projectiles that I have with complex particle systems that turn off at different points when they die. It's not hard to get it all turned back on again or anything, it just seems like I might be missing something. Usually when I feel like I'm doing a lot of manual work with something, I step back and reconsider to make sure that this is the most effective route. It seems to be, but I just feel like there's something wrong with my approach.

    Any advice? Am I on the right track, or way off base?
    Thanks everyone!
     
  15. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Pooling is mainly to avoid frame rate stutters due to GC. If they aren't occurring in your game, don't worry about pooling.
     
    Eluem likes this.
  16. Eluem

    Eluem

    Joined:
    Apr 13, 2013
    Posts:
    57
    Thank you. I built a simple generic pooling system, but some of the specific implementation details can vary per object and can cause quite a headache to try to make it work for every single possible object. With your advice, I'll only implement it for objects that I'm noticing cause stutter on instantiation/GC. Thanks again!