Search Unity

Feedback Optimization and Object Pooling

Discussion in '2D' started by indie6, Aug 8, 2019.

  1. indie6

    indie6

    Joined:
    Dec 15, 2012
    Posts:
    101
    Hello everyone

    I am making a 2D level based rope swing platformer for mobile devices. A level is made up of items such as spikes, laser, rocket launcher, etc.

    My question is related to the pooling of objects. So, the basic flow is like this... An ObjectPool creates a pool of all the items. LevelManager takes level data and creates the level. It takes the required items from the pool and places them in the level

    Now here is what's bothering me, I have to code Default and OnRecycle state for every item, and there are 10+ items and every item has different interaction with player. It gets hectic as there always comes a point where I miss some variable that is required to be in a default state. This results in bugs, and I have to spend time debugging the game.

    Generally, Object Pooling is usually used for frequently used objects.. like bullets in a shooting game.. but here I am just loading the items once per level. So what do you people suggest? Previously I was just instantiating the items and had no stutter or performance issue even on a low-end device

    Now I am wondering, is it really worth pooling? Am I over-engineering this?

    On a side note: sfx, vfx, items like rockets and bullets are already being pooled and reused.. and nothing in the level is instantiated on runtime
     
  2. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Object pooling is a trade-off.

    A pooled object is already loaded into the scene, which gives it the benefit of being "instantiated" (enabled) and "destroyed" (disabled) without having to be re-loaded, and there's no garbage collection involved in the process.

    The cost of object pooling, however, is that it will use more memory. Every object that exists in your scene also exists somewhere in your system's memory, and the size/complexity of the object determines how much memory it uses. This means if you're pooling objects that aren't frequently being used, then they're just sitting idle and taking up unnecessary memory that can be used for other tasks.

    You need to determine where and when object pooling is appropriate. Bullets in a shooting game are typically pooled because they're very small objects that are used very frequently. In this case, the memory issue is practically non-existent, since a bullet doesn't sit idle in the pool for long. If the bullets were instantiated/destroyed instead, there would be lots of memory allocation and garbage collection calls happening very frequently, which are slower operations and not ideal for gameplay.

    An example of object pooling not being the ideal solution is when you're loading an entire environment/level/zone/whatever. These typically consist of a large amount of complex objects which use up a lot more memory than something like a bullet would.
    Now imagine if you had 10 of these levels. Pooling them would mean you would first need to instantiate them all at once, which would be incredibly slow in itself, and then on top of that, the user's system would need a ton of RAM just to keep all of these level instances in memory, which would be unnecessary since they're only going to switch between levels occasionally, meaning the 9 inactive levels in the pool are just sitting there and eating up resources for no reason.

    In this scenario, it would be preferable to just instantiate/destroy levels, as the other side of the trade-off is ideal. The cost here is that every level needs to be loaded & garbage collected, and the benefit is that you save much more memory space. Plus, since levels would only be occasionally switched, the expensive allocation and garbage collection operations are negligible, as they would just be part of a level's loading process, rather than during the actual gameplay.

    To summarize, if you're going to be constantly reusing objects at frequent intervals, then object pooling is likely the ideal choice, but if you have some objects that rarely or never get reused, then object pooling may be a hindrance instead. If you're unsure about object pooling for a certain situation, then test out both ways using the profiler and use your judgment to determine if the memory cost or the loading cost is preferred.
     
    Last edited: Aug 10, 2019
    Heemo2000 likes this.