using System; using System.Collections.Generic; using UnityEngine; public class Pool : MonoBehaviour { public static Pool Instance; [SerializeField] private List<PoolTable> items = new List<PoolTable>(); private Dictionary<GameObject, PoolTable> overriddenPoolTables = new Dictionary<GameObject, PoolTable>(); private Dictionary<GameObject, PoolInstance> poolInstances = new Dictionary<GameObject, PoolInstance>(); private Dictionary<GameObject, PoolTable> poolTables = new Dictionary<GameObject, PoolTable>(); public Preallocation[] preallocations; private void Awake() { Instance = this; foreach (Preallocation preallocation in this.preallocations) { this.DoPreallocate(preallocation.prefab, preallocation.count); } } public static void Despawn(GameObject obj) { if (Instance != null) { Instance.DoDespawn(obj); } } public static void Despawn<T>(T obj) where T: Component { if (Instance != null) { Instance.DoDespawn(obj.gameObject); } } public static void DespawnAll() { if (Instance != null) { Instance.DoDespawnAll(); } } private void DoDespawn(GameObject obj) { PoolInstance instance; if (this.poolInstances.TryGetValue(obj, out instance)) { PoolTable table = instance.Table; if (table != null) { instance.InUse = false; table.Despawn(obj); base.enabled = true; return; } } UnityEngine.Object.Destroy(obj); } private void DoDespawnAll() { foreach (KeyValuePair<GameObject, PoolInstance> pair in this.poolInstances) { PoolInstance instance = pair.Value; if (instance.Table != null) { instance.InUse = false; instance.Table.Despawn(pair.Key); } } base.enabled = true; } private void DoPreallocate(GameObject prefab, int count) { this.GetOrCreateTable(prefab).Preallocate(count); } private void DoReplace(GameObject prefab, GameObject otherPrefab) { PoolTable table; if (!this.poolTables.TryGetValue(prefab, out table)) { Debug.LogError("Prefab does not exist to replace: " + prefab.name + " with: " + otherPrefab.name); } else if (table.Prefab != otherPrefab) { PoolTable table2; foreach (KeyValuePair<GameObject, PoolInstance> pair in this.poolInstances) { if (pair.Value.Table == table) { pair.Value.InUse = false; table.Despawn(pair.Key); } } Instance.enabled = true; if (this.overriddenPoolTables.TryGetValue(otherPrefab, out table2)) { this.overriddenPoolTables.Remove(otherPrefab); } else { table2 = new PoolTable(otherPrefab); this.items.Add(table2); table2.Preallocate(table.ActiveCount + table.FreeCount); } this.overriddenPoolTables[table.Prefab] = table; this.poolTables[prefab] = table2; } } private GameObject DoSpawn(GameObject prefab, Vector3 position, Quaternion rotation) { base.enabled = true; PoolTable orCreateTable = this.GetOrCreateTable(prefab); GameObject instance = orCreateTable.Spawn(position, rotation); this.poolInstances[instance] = new PoolInstance(instance, true, orCreateTable); return instance; } public int GetActiveCount(GameObject prefab) { PoolTable table; if (this.poolTables.TryGetValue(prefab, out table)) { return table.ActiveCount; } return 0; } private PoolTable GetOrCreateTable(GameObject prefab) { PoolTable table; if (!this.poolTables.TryGetValue(prefab, out table)) { table = new PoolTable(prefab); this.poolTables[prefab] = table; this.items.Add(table); } return table; } public PoolInstance GetPoolInstance(GameObject obj) { PoolInstance instance; this.poolInstances.TryGetValue(obj, out instance); return instance; } public static PoolTable GetTable(GameObject prefab) { return ((Instance == null) ? null : Instance.GetOrCreateTable(prefab)); } private void LateUpdate() { foreach (PoolTable table in this.items) { table.Update(); } base.enabled = false; } public static void Replace(GameObject prefab, GameObject otherPrefab) { if (Instance != null) { Instance.DoReplace(prefab, otherPrefab); } } public static void Revert(GameObject prefab) { if (Instance != null) { Instance.DoReplace(prefab, prefab); } } public static GameObject Spawn(GameObject prefab) { return ((Instance == null) ? null : Instance.DoSpawn(prefab, Vector3.zero, Quaternion.identity)); } public static T Spawn<T>(T prefab) where T: Component { if (Instance != null) { GameObject obj2 = Instance.DoSpawn(prefab.gameObject, Vector3.zero, Quaternion.identity); if (obj2 != null) { return obj2.GetComponent<T>(); } } return null; } public static GameObject Spawn(GameObject prefab, Vector3 position, Quaternion rotation) { return ((Instance == null) ? null : Instance.DoSpawn(prefab, position, rotation)); } public static T Spawn<T>(T prefab, Vector3 position, Quaternion rotation) where T: Component { if (Instance != null) { GameObject obj2 = Instance.DoSpawn(prefab.gameObject, position, rotation); if (obj2 != null) { return obj2.GetComponent<T>(); } } return null; } public List<PoolTable> Items { get { return this.items; } } [Serializable] public class Preallocation { public int count; public GameObject prefab; } }