using System; using System.Collections; using System.Collections.Generic; using UnityEngine; [Serializable] public struct InstantiationPrefabSettings { public GameObject prefab; public int minCount; public int maxCount; } public class Pool { private InstantiationPrefabSettings settings; private Queue remainingGameObjects = new Queue(); private HashSet instancedGameObjects = new HashSet(); public Pool(InstantiationPrefabSettings settings) { this.settings = settings; } public void Init() { remainingGameObjects = new Queue(); instancedGameObjects = new HashSet(); for(int n=0;n 0) { instance = remainingGameObjects.Dequeue(); instance.SetActive(true); instancedGameObjects.Add(instance); } else if(remainingInstantiableCount > 0) { instance = GameObject.Instantiate(settings.prefab, Vector3.zero, Quaternion.identity); instancedGameObjects.Add(instance); } if(instance != null) { instance.transform.parent = null; PoolableMonoBehaviour poolableMonoBehaviour = instance.GetComponent(); if(poolableMonoBehaviour != null) { poolableMonoBehaviour.OnRetrieve(); } } return instance; } public void ReturnInstance(GameObject gameObj) { int remainingInstanceCount = remainingGameObjects.Count; if(remainingInstanceCount < settings.minCount) { PoolableMonoBehaviour poolableMonoBehaviour = gameObj.GetComponent(); if(poolableMonoBehaviour != null) { poolableMonoBehaviour.OnReturn(); } gameObj.SetActive(false); gameObj.transform.parent = PoolManager.Instance.transform; remainingGameObjects.Enqueue(gameObj); } else { GameObject.Destroy(gameObj); } } } public class PoolManager : MonoBehaviour { public InstantiationPrefabSettings[] InstantiableGameObjects = new InstantiationPrefabSettings[0]; private Dictionary pools = new Dictionary(); private Dictionary instanceToPrefabDict = new Dictionary(); private static PoolManager instance; public static PoolManager Instance { get { return instance; } } protected void Awake() { instance = this; } protected void Start() { foreach(InstantiationPrefabSettings poolInstantiationSettings in InstantiableGameObjects) { Pool pool = new Pool(poolInstantiationSettings); pools[poolInstantiationSettings.prefab] = pool; pool.Init(); } } public GameObject GetInstance(GameObject prefab) { GameObject instance = pools[prefab].GetInstance(); if(instance != null) { instanceToPrefabDict[instance] = prefab; } return instance; } public void ReturnInstance(GameObject gameObj) { GameObject prefab = instanceToPrefabDict[gameObj]; pools[prefab].ReturnInstance(gameObj); } }