XPool - Object Pooling System for Unity

Created by Hiroya Aramaki (Makihiro)
What is XPool ?
XPool is an object pooling library for Unity.
This was developed to be able to do all the pooling expected in application development with just this library.
- All your classes can be pooled.
- Short code, easy to use.
- Fast performance
- Scalability
- Tested. It works stably.
Table of Contents
📥 Installation
Download any version from releases.
Releases: https://github.com/mackysoft/XPool/releases
Install via PackageManager
Or, you can add this package by opening PackageManager and entering
https://github.com/mackysoft/XPool.git?path=Assets/MackySoft/MackySoft.XPool
from the Add package from git URL option.
Install via Open UPM
Or, you can install this package from the Open UPM registry.
More details here.
openupm add com.mackysoft.xpool
🔰 Usage
The full Scripting API is here.
Scripting API: https://mackysoft.github.io/XPool/api/MackySoft.XPool.html
Unity Object Pool (GameObject, Component)
Pooling of Unity Object (GameObject, Component) can be performed using GameObjectPool or ComponentPool<T>.
These hierarchical objects can be rented by writing them in a similar way to Instantiate method.
// Example code is being written...
ParticleSystem Pool
Optimized pools are available for some of the components implemented in Unity.
This is an example of ParticleSystemPool usage.
public class HitParticleSystemEmitter : MonoBehaviour {
    [SerializeField]
    ParticleSystemPool m_HitParticleSystemPool = new ParticleSystemPool();
    void OnCollisionEnter (Collision collision) {
        // The rented ParticleSystem is automatically returned to the pool when completed.
        m_HitParticleSystemPool.Rent(collision.contacts[0],Quaternion.identity);
    }
}
If you need an optimized pool for other components, please refer to the How to write custom pool ? section, or give me feedback via issues or pull requests.
Object Pool (Pure C# Object)
FactoryPool<T> can be used to pool Pure C# Object.
Unity Object are not supported, as they behave differently from Pure C# Object in that they can be set to null externally with
Destroymethod.
// Give the capacity and factory method to the constructor.
var pool = new FactoryPool<MyClass>(8,() => new MyClass());
// Create new instance by factory if pool is empty.
MyClass instance = pool.Rent();
// Return instance to the pool.
pool.Return(instance);
 Collection Pool (T[], List<T>, Qeueue<T>, Stack<T>, HashSet<T>, Dictionary<TKey,TValue>) 
An optimized pool is provided for the generic collections provided in .NET Framework.
// Rent an array from the pool. 
// Note that the array length to be rented is the next two powers of minimumLength.
T[] array = ArrayPool<T>.Shared.Rent(minimumLength: 10);
// Return array to the pool.
ArrayPool<T>.Shared.Return(array);
// ListPool<T>, QueuePool<T>, StackPool<T>, HashSetPool<T>, DictionaryPool<TKey,TValue> are also available.
List<T> list = ListPool<T>.Shared.Rent();
Queue<T> queue = QueuePool<T>.Shared.Rent();
Stack<T> stack = StackPool<T>.Shared.Rent();
HashSet<T> hashSet = HashSetPool<T>.Shared.Rent();
Dictionary<TKey,TValue> dictionary = DictionaryPool<TKey,TValue>.Shared.Rent();
Non allocated collections
You can use the TemporaryCollections API that leverages ArrayPool<T>.
These collections are a struct and internally use array rented from ArrayPool<T>.
Therefore, it is fast and non-allocation.
// Create a temporary array.
var array = TemporaryArray<T>.Create(10);
// You must release collection when you are done using it.
array.Dispose();
// TemporaryList<T>, TemporaryQueue<T>, TemporaryStack<T> are also available.
TemporaryList<T> list = TemporaryList<T>.Create();
TemporaryQueue<T> queue = TemporaryQueue<T>.Create();
TemporaryStack<T> stack = TemporaryStack<T>.Create();
How to write custom pool ?
If you want to implement a more customized pool, you can quickly create one by using the provided base classes.
The base class of the pool is in the ObjectModel namespace.
- MackySoft.XPool.ObjectMode.PoolBase<T>
- MackySoft.XPool.Unity.ObjectModel.UnityObjectPoolBase<T>
- MackySoft.XPool.Unity.ObjectModel.ComponentPoolBase<T>
using MackySoft.XPool.ObjectModel; // PoolBase<T> is here.
public class MyPool : PoolBase<MyClass> {
    public MyPool () {
    }
    public MyPool (MyClass original,int capacity) : base(original,capacity) {
    }
    // Called when Rent is invoked and there are no instances in the pool.
    protected override MyClass Factory () {
        return new MyClass();
    }
    // Called when an instance is rented from the pool.
    // This is also the case when a new instance is created by the Factory.
    protected override void OnRent (MyClass instance) {
    }
    // Called when an instance is returned to the pool.
    protected override void OnReturn (MyClass instance) {
    }
    // Called when the capacity is exceeded and the instance cannot be returned to the pool,
    // or when the instance is released by the ReleaseInstances method.
    protected override void OnRelease (MyClass instance) {
    }
}
ParticleSystemPool implementation
As an example, ParticleSystemPool is implemented using ComponentPoolBase<T>.
Its functionality has been optimized for ParticleSystem.
using System;
using UnityEngine;
using MackySoft.XPool.Unity.ObjectModel; // ComponentPoolBase<T> is here.
[Serializable]
public class ParticleSystemPool : ComponentPoolBase<ParticleSystem> {
    [SerializeField]
    bool m_PlayOnRent;
    public bool PlayOnRent { get => m_PlayOnRent; set => m_PlayOnRent = value; }
    public ParticleSystemPool () {
    }
    public ParticleSystemPool (ParticleSystem original,int capacity) : base(original,capacity) {
    }
    protected override void OnCreate (ParticleSystem instance) {
        var main = instance.main;
        main.stopAction = ParticleSystemStopAction.Callback;
        var trigger = instance.gameObject.AddComponent<ParticleSystemStoppedTrigger>();
        trigger.Initialize(instance,this);
    }
    protected override void OnRent (ParticleSystem instance) {
        if (m_PlayOnRent) {
            instance.Play(true);
        }
    }
    protected override void OnReturn (ParticleSystem instance) {
        instance.Stop(true,ParticleSystemStopBehavior.StopEmitting);
    }
    protected override void OnRelease (ParticleSystem instance) {
        UnityEngine.Object.Destroy(instance.gameObject);
    }
    public class ParticleSystemStoppedTrigger : MonoBehaviour {
        ParticleSystem m_ParticleSystem;
        IPool<ParticleSystem> m_Pool;
        internal void Initialize (ParticleSystem ps,IPool<ParticleSystem> pool) {
            m_ParticleSystem = ps;
            m_Pool = pool;
        }
        void OnParticleSystemStopped () {
            m_Pool?.Return(m_ParticleSystem);
        }
    }
}
✉ Help & Contribute
I welcome feature requests and bug reports in issues and pull requests.
If you feel that my works are worthwhile, I would greatly appreciate it if you could sponsor me.
GitHub Sponsors: https://github.com/sponsors/mackysoft
📔 Author Info
Hiroya Aramaki is a indie game developer in Japan.
- Twitter: https://twitter.com/makihiro_dev
- Blog: https://mackysoft.net/blog
📜 License
This library is under the MIT License.