Skip to content

GameDevBox/uPools

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

31 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Pool System (uPools + Pool Manager)

A lightweight and flexible object pooling system for Unity. This project is a heavily-modified fork of uPools, featuring an entirely upgraded core pooling manager, advanced configuration options, and several new systems built on top of the original library.

πŸ“Ί Watch the full tutorial on YouTube: https://youtu.be/kooOjK0K0bk

Overview

A lightweight and highly flexible object pooling system for Unity with category support, weighted instantiation, callbacks, and advanced spawn behaviors.

Furthermore, it provides support for asynchronous object pooling using UniTask and object pooling with Addressables.

Features

  • Heavily upgraded core pooling manager built on top of uPools

  • Scriptable Pool Configs for fully data-driven pooling setup

  • Support for multiple prefabs per pool key

  • Four instantiation modes: Sequential, Random, Weighted Random, First-Only

  • Prefab categories with automatic grouping and filtering

  • Customizable transform reset system

    • Prefab Defaults

    • Custom Defaults

    • Provided Runtime Values

    • Keep Current Transform

  • Advanced overflow handling

    • Block

    • Reuse Oldest

    • Reuse Random

  • Initial & Maximum pool size control with optional prewarm on start

  • Built-in logging tools and automatic validation for broken configs

  • Callback system with IPoolCallbackReceiver (OnRent, OnReturn, OnInitialize, OnDestroy)

    • Works on root and child objects
  • Full support for uPools base features

  • Generic ObjectPool

  • SharedGameObjectPool as an Instantiate/Destroy replacement

  • UniTask async pooling

  • Addressables pooling

πŸš€ Setup & Installation

Highly recommend watching the tutorial: Tutorial

  1. Download the package or drag the folders to the project.

  2. Add the Pool System Manager: The PoolSystemManager is the core engine that handles all pooling logic.

  3. Create Pool Configurations: Each pool is defined by a PoolConfig.

You can create them through:

  • Right-click in Project Window β†’ Create β†’ uPools β†’ PoolConfig

How to Use in Code

🟒 Get (Spawn)

GameObject bullet = PoolSystemManager.Instance.Get("Bullet");

With position/rotation:

PoolSystemManager.Instance.Get(
   "Bullet",
   position: new Vector3(0, 1, 0),
   rotation: Quaternion.identity
);

Get a component directly:

var enemy = PoolSystemManager.Instance.Get<Enemy>("Enemy");

πŸ”΄ Release (Despawn)

Release a single object:

PoolSystemManager.Instance.Release(gameObject);

Release by key:

PoolSystemManager.Instance.Release("Bullet");


Release multiple:

```cs
PoolSystemManager.Instance.Release("Bullet", 5);

Release all objects from a pool:

PoolSystemManager.Instance.ReleaseAll("Bullet");

Release all pools:

PoolSystemManager.Instance.ReleaseAll();

πŸ”„ Callbacks

You can insert custom actions on Rent and Return by implementing IPoolCallbackReceiver. To run logic when the object is:

  • Created

  • Rented (spawned)

  • Returned (despawned)

  • Destroyed from pool (destroy array)

public class ExamplePoolable: MonoBehaviour, IPoolCallbackReceiver
{
    public void OnInitialize() { }
    public void OnRent() { }
    public void OnReturn() { }
    public void OnPoolDestroy() { }
}

In the case of GameObjectPool or SharedGameObjectPool, this component will be retrieved from the object and its child objects, and the callbacks will be invoked accordingly. For other object pools like ObjectPool<T> or pools that inherit from ObjectPoolBase<T>, the callbacks are invoked for objects that implement IPoolCallbackReceiver.

If you create your own object pool by implementing IObjectPool<T, you will need to handle the IPoolCallbackReceiver calls yourself. Implement the necessary logic to invoke these callbacks as needed.

πŸ“Š Tools & Debugging

Log pool stats:

PoolSystemManager.Instance.LogPoolStatistics();

Get active or inactive counts:

PoolSystemManager.Instance.GetActiveCount("Enemy");
PoolSystemManager.Instance.GetInactiveCount("Enemy");

Get total objects ever created

int totalCreated = PoolSystemManager.Instance.GetTotalCreated("Bullet");

Check if a pool exists

bool exists = PoolSystemManager.Instance.PoolExists("Bullet");

Clear a pool:

PoolSystemManager.Instance.ClearPool("Enemy");

Get all keys:

PoolSystemManager.Instance.GetAllPoolKeys();

πŸ”§ Transform Reset Modes

Every spawned object supports 4 reset strategies:

  • UsePrefabDefaults – resets to prefab transform

  • UseCustomDefaults – uses values defined in the PoolConfig

  • UseProvidedValues – uses values passed into Get()

  • KeepCurrent – leaves transform untouched

Set manually:

PoolSystemManager.Instance.SetPoolTransformMode("Bullet", TransformResetMode.KeepCurrent);

Set Custom Defaults

PoolSystemManager.Instance.SetPoolTransformDefaults(
    "Enemy",
    new Vector3(0, 2, 0),
    Quaternion.identity,
    Vector3.one * 2f
);

Get Reset Mode

TransformResetMode mode =
    PoolSystemManager.Instance.GetPoolTransformMode("Enemy");

πŸ—‚ Category & Hierarchy Helpers

Get parent transform of all pools

Transform root = PoolSystemManager.Instance.GetCurrentPoolParent();

Get all category root transforms

var categories = PoolSystemManager.Instance.GetCategoryParents();

πŸ“š Key & Pool Management

Get all pool keys

IEnumerable<string> keys = PoolSystemManager.Instance.GetAllPoolKeys();

Get as string[]

string[] keysArray = PoolSystemManager.Instance.GetAllPoolKeysArray();

Get instantiation mode

InstantiationMode mode =
    PoolSystemManager.Instance.GetPoolInstantiationMode("Bullet");

UniTask

uPools supports asynchronous object pooling using UniTask. When you add UniTask to your project, you can use AsyncObjectPool<T>, AsyncObjectPoolBase<T>, and IAsyncObjectPool<T> for asynchronous object pooling. These pools provide asynchronous versions of Rent, Prewarm, and CreateInstance while behaving like regular ObjectPool<T> in other aspects.

Addressables

When using Addressables to generate GameObjects, you need to manage the resources of the loaded Prefabs. uPools offers AddressableGameObjectPool for this purpose, which can be used similarly to GameObjectPool.

// Address of the Prefab
var key = "Address";
var pool = new AddressableGameObjectPool(key);

// Usage is the same as GameObjectPool
var instance1 = pool.Rent();
var instance2 = pool.Rent(new Vector3(1f, 2f, 3f), Quaternion.identity);

pool.Return(instance1);
pool.Return(instance2);

pool.Dispose();

Summary

A complete, optimized, and fully customizable Unity Object Pooling System with auto-categorizing, transform settings, overflow behavior, and callback support. This is the system I use across multiple projects β€” stable, flexible, and easy to extend.

Original Upools: https://github.com/AnnulusGames/uPools

You can also use the asynchronous version AsyncAddressableGameObjectPool by introducing UniTask.

πŸ”₯follow my YouTube @GameDevBox to find more Tutorials and Tips: GameDevBox

πŸ”₯See the tutorial for how you can set it up: https://youtu.be/kooOjK0K0bk

Social Media:

β€’ X/Twitter β€’ Instagram: β€’ LinkedIn: β€’ Discord Server: β€’ itch.io: β€’ Youtube Subscribe:

About

A lightweight and flexible object pooling system for Unity - Extended

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C# 100.0%