using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.VFX; using Util; //thomas09 public class NetworkPooler : MonoBehaviour { /// /// used in a list for multiple object pools. /// [System.Serializable] public class Pool { /// Name of prefab public string tag; /// Prefab gameObject public GameObject prefab; /// Size of the current pool public int size; } public static NetworkPooler Instance; public List Pools = new List(); public Dictionary> poolDictionary; private void Awake() => Instance = this; void Start() { poolDictionary = new Dictionary>(); foreach (Pool pool in Pools) { Queue objectPool = new Queue(); for (int i = 0; i < pool.size; i++) { try { GameObject obj = Instantiate(pool.prefab, transform); obj.SetActive(false); objectPool.Enqueue(obj); } catch (Exception e) { Debug.Log("Error: " + e.Message); } } poolDictionary.Add(pool.tag, objectPool); } } public static string GetBaseName(string name) { return name.Split('(')[0]; } public GameObject PooledInstantiate(string tag, Vector3 position, Quaternion rotation) { if (!poolDictionary.ContainsKey(tag)) { Debug.LogError($"Pool with tag {tag} does not exist!"); return null; } //if you're requesting a prefab thats not available, make a new one and add it to the pool. if (poolDictionary[tag].Count <= 0) { foreach (Pool pool in Pools) { if(pool.tag == tag) { GameObject additionalPoolObject = Instantiate(pool.prefab); poolDictionary[tag].Enqueue(additionalPoolObject); } } } if (poolDictionary[tag].Count > 0) { GameObject pooledObject = poolDictionary[tag].Dequeue(); if (pooledObject != null) { pooledObject.SetActive(true); pooledObject.transform.SetParent(null); pooledObject.transform.position = position; pooledObject.transform.rotation = rotation; return pooledObject; } } Debug.LogError($"Error retrieving object {tag} from the pool."); return null; } //use this if you want to play an effect and then remove it fairly quickly. Like a hit effect or muzzle flash etc. public GameObject PooledPlayEffect(string effectTag, Vector3 position, Quaternion rotation, float duration) { GameObject vfxGameObj = PooledInstantiate(effectTag, position, rotation); PooledDestroy(effectTag, vfxGameObj, duration); return vfxGameObj; } public void PooledDestroy(string tag, GameObject objectToReuse) { PoolDestroyInternal(tag, objectToReuse); } public void PooledDestroy(string tag, GameObject objectToReuse, float time) { StartCoroutine(TimedPoolDestroy(tag, objectToReuse, time)); } private IEnumerator TimedPoolDestroy(string tag, GameObject objectToReuse, float time) { yield return new WaitForSeconds(time); PoolDestroyInternal(tag, objectToReuse); } private void PoolDestroyInternal(string tag, GameObject objectToReuse) { if (!poolDictionary.ContainsKey(tag)) { Debug.LogError($"An error occurred retreiving {objectToReuse.name} from pool dictionary {tag}, is the tag correct?"); return; } if (!poolDictionary[tag].Contains(objectToReuse)) { poolDictionary[tag].Enqueue(objectToReuse); objectToReuse.transform.SetParent(transform); objectToReuse.SetActive(false); } } }