Below is an example of an object pool that allows renting and returning of a given object type. To create the object pool a Func for the create function and an Action to destroy the object are required to give the user flexibility. On requesting an object when the pool is empty a new object will be created and on requesting when the pool has objects then objects are removed from the pool and returned.
Object Pool
public class ResourcePool<T> where T : class
{
private readonly List<T> objectPool = new List<T>();
private readonly Action<T> cleanUpAction;
private readonly Func<T> createAction;
public ResourcePool(Action<T> cleanUpAction, Func<T> createAction)
{
this.cleanUpAction="/?originalUrl=https%3A%2F%2Friptutorial.com%2FcleanUpAction%3B%2520%2520%2520%2520%2520%2520%2520%2520this.createAction%2520%3D%2520createAction%3B%2520%2520%2520%2520%257D%2520%2520%2520%2520public%2520void%2520Return(T%2520resource)%2520%2520%2520%2520%257B%2520%2520%2520%2520%2520%2520%2520%2520this.objectPool.Add(resource)%3B%2520%2520%2520%2520%257D%2520%2520%2520%2520private%2520void%2520PurgeSingleResource()%2520%2520%2520%2520%257B%2520%2520%2520%2520%2520%2520%2520%2520var%2520resource%2520%3D%2520this.Rent()%3B%2520%2520%2520%2520%2520%2520%2520%2520this.cleanUpAction(resource)%3B%2520%2520%2520%2520%257D%2520%2520%2520%2520public%2520void%2520TrimResourcesBy(int%2520count)%2520%2520%2520%2520%257B%2520%2520%2520%2520%2520%2520%2520%2520count%2520%3D%2520Math.Min(count%2C%2520this.objectPool.Count)%3B%2520%2520%2520%2520%2520%2520%2520%2520for%2520(int%2520i%2520%3D%25200%3B%2520i%2520%26lt%3B%2520count%3B%2520i%2B%2B)%2520%2520%2520%2520%2520%2520%2520%2520%257B%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520this.PurgeSingleResource()%3B%2520%2520%2520%2520%2520%2520%2520%2520%257D%2520%2520%2520%2520%257D%2520%2520%2520%2520public%2520T%2520Rent()%2520%2520%2520%2520%257B%2520%2520%2520%2520%2520%2520%2520%2520int%2520count%2520%3D%2520this.objectPool.Count%3B%2520%2520%2520%2520%2520%2520%2520%2520if%2520(count%2520%3D%3D%25200)%2520%2520%2520%2520%2520%2520%2520%2520%257B%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520Debug.Log(%26quot%3BCreating%2520new%2520object.%26quot%3B)%3B%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520return%2520this.createAction()%3B%2520%2520%2520%2520%2520%2520%2520%2520%257D%2520%2520%2520%2520%2520%2520%2520%2520else%2520%2520%2520%2520%2520%2520%2520%2520%257B%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520Debug.Log(%26quot%3BRetrieving%2520existing%2520object.%26quot%3B)%3B%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520T%2520resource%2520%3D%2520this.objectPool%5Bcount-1%5D%3B%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520this.objectPool.RemoveAt(count-1)%3B%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520return%2520resource%3B%2520%2520%2520%2520%2520%2520%2520%2520%257D%2520%2520%2520%2520%257D%257D%253C%2Fcode">
Sample usage
public class Test : MonoBehaviour
{
private ResourcePool<GameObject> objectPool;
[SerializeField]
private GameObject enemyPrefab;
void Start()
{
this.objectPool = new ResourcePool<GameObject>(Destroy,() => Instantiate(this.enemyPrefab) );
}
void Update()
{
// To get existing object or create new from pool
var newEnemy = this.objectPool.Rent();
// To return object to pool
this.objectPool.Return(newEnemy);
// In this example the message 'Creating new object' should only be seen on the frame call
// after that the same object in the pool will be returned.
}
}