25
\$\begingroup\$

I have read about this pattern several times (from a best-practices perspective):

Memory Allocation: Instead of instantiating the new object on the fly, always consider creating and using object pools. It will help to less memory fragmentation and make the garbage collector work less.

However, I don’t know what it actually means. How can I implement it?

For example, I can instantiate a GameObject using the Instantiate method of Unity?

Instantiate(prefab, new Vector3(2.0F, 0, 0), Quaternion.identity);

Is this use discouraged? What else can it mean?

\$\endgroup\$
  • \$\begingroup\$ First link on Google ;) unity3d.com/fr/learn/tutorials/topics/scripting/object-pooling \$\endgroup\$ – Hellium Sep 12 '17 at 8:57
  • \$\begingroup\$ Thanks Hellium I didn't watch the given video (too big) but the text really help me to understand "The act of instantiating and destroying are inefficient and can slow your projects down" \$\endgroup\$ – Muhammad Faizan Khan Sep 12 '17 at 9:32
  • 1
    \$\begingroup\$ Note that while this advice is common, it's not an absolute requirement for every game. Especially if you're making a small/short desktop game, jam submission, or prototype, you don't need to go out of your way to implement pooling. In my soak tests Unity holds up to even massive spawning & destruction better than we give it credit for. ;) But do consider pooling if you're making a long game where you don't want garbage to pile up and cause a stutter when it's collected later, or if you're targeting mobile platforms where any performance impact is felt more keenly. \$\endgroup\$ – DMGregory Sep 12 '17 at 11:11
  • \$\begingroup\$ Thanks @DMGregory You are right. your input is always valuable.We should not worry about object pooling in small games as it will require extra work in coding. \$\endgroup\$ – Muhammad Faizan Khan Sep 12 '17 at 11:52
  • 1
    \$\begingroup\$ This is a very common pattern, but make sure to temper it with the rule: "Profile first, then optimize." Its easy to optimize things that don't matter. \$\endgroup\$ – Cort Ammon Sep 12 '17 at 20:19
41
\$\begingroup\$

If you're planning to instantiate many instances of the same prefab, you should definitely think about using object pooling. Calling Unity's Instantiate function is one of the most taxing method calls you could make.

Object pooling is when you instantiate prefabs before they are used. They are deactivated immediately upon instantiation and reactivated only when they are needed. While this does increase memory usage, it avoids the CPU overhead of instantiating during gameplay.

For example, I'm currently working on a bullet hell game that requires hundreds of bullets to be spawned at runtime. I initially tried to make the game without object pooling but that ended up being a disaster ( less than 2 fps). Now, I pool 500 bullets before the game starts and the game runs astonishingly fast (200 fps).

There are situations where object pooling cannot be used. For instance, if you have a game where player input dictates what prefab is spawned, then you may have no choice but to use the normal Instantiate call. Object pooling is only possible when you know ahead of time what objects will be needed.

Sebastian Lague's YouTube tutorial is a great resource for learning about object pooling: https://youtu.be/LhqP3EghQ-Q

\$\endgroup\$
  • \$\begingroup\$ "The act of instantiating and destroying are inefficient and can slow your projects down" . this is the reason? So it means that we have to code a bit more (like activate deactive, or set position of bullet again so we can fire again) \$\endgroup\$ – Muhammad Faizan Khan Sep 12 '17 at 9:24
  • 12
    \$\begingroup\$ It might be worth mentioning allocation and garbage collection as major contributors to the cost of repeated instantiation & destruction. Generate enough garbage and eventually the whole game has to wait for the garbage collector to sweep it all up. ;) \$\endgroup\$ – DMGregory Sep 12 '17 at 11:05
  • 3
    \$\begingroup\$ @corsiKa that would be an 80's era optimisation. Unity can just deactivate the prefabs in question, making its systems ignore it. \$\endgroup\$ – congusbongus Sep 13 '17 at 1:52
  • 2
    \$\begingroup\$ "For instance, if you have a game where player input dictates what prefab is spawned, then you may have no choice but to use the normal Instantiate call." - Not really. You could easily have multiple object pools for different prefabs allocated to the desired sizes at startup (or scene load). Or, if one wanted to make it, an object pool that stores multiple prefab types might also work. \$\endgroup\$ – Ethan Bierlein Sep 13 '17 at 13:03
  • 1
    \$\begingroup\$ @DMGregory In a typical GC environment, de-allocation is most of the cost; in a typical non-GC environment, allocation is most of the cost. Object pooling works great for both, they're really just two sides of the same coin for the most part. In the extreme case, old games used to be written with all the objects "allocated" from the get-go - very little or no memory de/allocation while the game was running. You didn't really use anything that wasn't "pooled" in some way. Since Unity uses a lot of real-time "metadata", pooling can help quite a bit - though it can also be trickier to implement. \$\endgroup\$ – Luaan Sep 13 '17 at 13:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.