using System.Collections.Generic;using UnityEngine;
namespace FE.ObjectPool{ public abstract class PoolBase<T> : MonoBehaviour where T : MonoBehaviour { /// <summary> /// Prefab to be pooled, will use it as a template to instantiate new items /// </summary> [SerializeField] private T _objectPrefab; /// <summary> /// Pool size /// </summary> [SerializeField] private int _initialCount;
/// <summary> /// pooled items /// </summary> private readonly Queue<T> m_poolQueue = new();
/// <summary> /// Initializes the pool with the serialized prefab and count /// </summary> protected void InitPool() { for (int i = 0; i < _initialCount; i++) { T obj = Instantiate(_objectPrefab, transform); m_poolQueue.Enqueue(obj); obj.gameObject.SetActive(false); } }
/// <summary> /// Can be used to re-initialize the pool with different prefab and count values /// </summary> /// <param name="prefab"></param> /// <param name="count"></param> protected void InitPool(T prefab, int count) { _objectPrefab = prefab; _initialCount = count; InitPool(); }
/// <summary> /// Selects an item, returns and removes it from the pool. CAREFUL: Doesn't expands the pool if it's empty. /// </summary> /// <returns>An item form the pool</returns> public T Get() { T obj = m_poolQueue.Dequeue(); obj.gameObject.SetActive(true); m_poolQueue.Enqueue(obj);
return obj; }
/// <summary> /// Selects an item, returns and removes it from the pool, places it at the given world position. /// CAREFUL: Doesn't expands the pool if it's empty. /// </summary> /// <param name="position"></param> /// <returns></returns> public T Get(Vector3 position) { T obj = m_poolQueue.Dequeue(); obj.transform.position = position; obj.gameObject.SetActive(true); m_poolQueue.Enqueue(obj);
return obj; }
/// <summary> /// Returns an item to the pool, doesn't disables the GameObject. /// </summary> /// <param name="obj">Item to return</param> public void Return(T obj) { obj.gameObject.SetActive(false); m_poolQueue.Enqueue(obj); } }}
•using System.Collections.Generic;using UnityEngine;
namespace FE.ObjectPool{ public class ObjectPool<T> where T : MonoBehaviour { private readonly int expand_step = 10;
private readonly Queue<T> m_items; private readonly Transform m_parent;
private readonly T m_prefab;
public ObjectPool(T prefab, int count) { m_items = new Queue<T>(count); m_prefab = prefab; InitializePool(prefab, count); }
public ObjectPool(T prefab, int count, Transform parent) { m_items = new Queue<T>(count); m_prefab = prefab; m_parent = parent; InitializePool(prefab, count, parent); } public ObjectPool(T prefab, int count, int expandStep, Transform parent) { m_items = new Queue<T>(count); expand_step = expandStep; m_prefab = prefab; m_parent = parent; InitializePool(prefab, count, parent); }
public T Get() { if (m_items.Count == 0) { int c = 0; if (expand_step == 0) { Debug.LogWarning("Expansion step is 0, pool is empty!"); } else { while (c < expand_step) { InstantiateInstance(m_prefab, m_parent); c++; } } }
return m_items.Dequeue(); }
public void Return(T t) { m_items.Enqueue(t); }
private void InitializePool(T prefab, int count) { for (int i = 0; i < count; i++) InstantiateInstance(prefab); }
private void InitializePool(T prefab, int count, Transform parent) { for (int i = 0; i < count; i++) InstantiateInstance(prefab, parent); }
private void InstantiateInstance(T prefab) { T instance = Object.Instantiate(prefab); m_items.Enqueue(instance); instance.gameObject.SetActive(false); }
private void InstantiateInstance(T prefab, Transform parent) { T instance = Object.Instantiate(prefab, parent, true); m_items.Enqueue(instance); instance.gameObject.SetActive(false); } }}