I am trying to create a wrapper around Unity’s built it object pooling. It isn’t all that good for expandability so I thought a wrapped would make it better for it.
It’s a pretty straight forward wrapper with two classes. A PoolObject class that any object that is pooled will inherit from and a Pool class that holds the pool for the inherited class.
Here is the PoolObject which all pooled objects inherit from.
public abstract class PoolObject : MonoBehaviour
{
public bool Active { get => gameObject.activeSelf; set => gameObject.SetActive(value); }
public IObjectPool<PoolObject> Pool { get; set; }//This is the part I am having problems with
public void Release()
{
OnRelease();
if (Pool != null)
{
Pool.Release(this);
}
else
{
Destroy(gameObject);
}
}
protected virtual void OnRelease()
{
}
}
Here is the Pool itself.
[System.Serializable]
public class Pool<T> where T : PoolObject
{
public event System.Action<T> OnCreated;
public event System.Action<T> OnGet;
public event System.Action<T> OnReleased;
public event System.Action<T> OnDestroyed;
public GameObject prefab;
private IObjectPool<T> pool;
public void Initialize()
{
if (prefab == null)
{
throw new System.Exception("Prefab is null!");
}
pool = new ObjectPool<T>(CreatObject, GetObject, ReleaseObject, DestroyObject);
}
private T CreatObject()
{
GameObject go = Object.Instantiate(prefab);
T obj = go.GetComponent<T>();
obj.Pool = pool as IObjectPool<PoolObject>;//How do I assign this without it being null?
Debug.Log(obj.Pool);
OnCreated?.Invoke(obj);
return obj;
}
private void GetObject(T obj)
{
Debug.Log($"Object {obj} Get!");
OnGet?.Invoke(obj);
}
private void ReleaseObject(T obj)
{
Debug.Log($"Object {obj} Released!");
OnReleased?.Invoke(obj);
obj.Active = false;
}
private void DestroyObject(T obj)
{
Debug.Log($"Object {obj} Destroyed!");
OnDestroyed?.Invoke(obj);
Object.Destroy(obj.gameObject);
}
public T Get()
{
return pool.Get();
}
}
The only time it does work is if I use Pool which is of course obvious. The rest of the time I get null when setting the Pool property on the PoolObject if I do something like Pool.
Is there something I am missing here. T is restricted to PoolObject or anything that inherits it, so it should always be IObjectPool if cast to that. At least that is my understanding. I’ve been programming for years and this is not something I have ever come across as a problem.
I know this is more of a C# thing and not Unity specific, but I am really stumped as to how to fix this.