I’m using UnityEngine.Pool in my project, but I ran into an issue.
When I set a low maxCapacity, if I take out more objects and then return them to the pool, the extra objects (beyond the capacity) are destroyed as expected. However, on subsequent calls to Get(), it looks like the pool is still (accidentally) trying to reuse those destroyed objects, which results in null.
Apart from simply increasing the maxCapacity, is there a recommended way to avoid this behavior?
using UnityEngine.Pool;
namespace Game.Controller
{
public abstract class SystemPool<T> : IObjectPool<T> where T : PoolingObject
{
#region ----- Component Config -----
// Collection checks will throw errors if we try to release an item that is already in the pool.
protected bool _collectionChecks = true;
protected int _maxPoolSize = 10;
private IObjectPool<T> _pool;
public int CountInactive { get; }
#endregion
#region ----- Constructor -----
public SystemPool(){}
#endregion
#region ----- Property -----
protected IObjectPool<T> Pool
{
get
{
if (_pool == null)
{
_pool = new ObjectPool<T>(CreatePooledItem, _OnTakeFromPool, _OnReturnedToPool,
_OnDestroyPoolObject, _collectionChecks, 10, _maxPoolSize);
}
return _pool;
}
}
#endregion
#region ----- Private Function -----
protected abstract T CreatePooledItem();
// Called when an item is returned to the pool using Release
private void _OnReturnedToPool(T obj)
{
obj.OnRelease();
obj.gameObject.SetActive(false);
}
// Called when an item is taken from the pool using Get
private void _OnTakeFromPool(T obj)
{
obj.OnGet();
obj.gameObject.SetActive(true);
}
// If the pool capacity is reached then any items returned will be destroyed.
// We can control what the destroy behavior does, here we destroy the GameObject.
private void _OnDestroyPoolObject(T obj)
{
obj.OnRelease();
// UnityEngine.Object.Destroy(obj.gameObject);
}
#endregion
#region ----- Implement Function -----
public T Get()
{
return Pool.Get();
}
public PooledObject<T> Get(out T v)
{
return Pool.Get(out v);
}
public void Release(T element)
{
lock (Pool)
{
if (element.IsRelease())
{
return;
}
element.Release();
element.gameObject.SetActive(false);
Pool.Release(element);
}
}
public void Clear()
{
Pool.Clear();
}
#endregion
}
}