Advertisement
Feynom

ObjectPooler

Mar 6th, 2023 (edited)
706
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.88 KB | Gaming | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. namespace Plugins.ObjectPooler
  6. {
  7.     public class ObjectPooler : MonoBehaviour
  8.     {
  9.         [Header("References")]
  10.         [SerializeField] private Transform _transform;
  11.  
  12.         [Header("Preferences")]
  13.         [SerializeField] private ObjectPool[] _poolList;
  14.  
  15.         private Dictionary<Pool, Queue<GameObject>> _pools;
  16.  
  17.         #region MonoBehaviour
  18.  
  19.         private void OnValidate()
  20.         {
  21.             _transform ??= GetComponent<Transform>();
  22.         }
  23.  
  24.         private void Awake()
  25.         {
  26.             Init();
  27.         }
  28.  
  29.         #endregion
  30.  
  31.         #region Fill
  32.  
  33.         private void Init()
  34.         {
  35.             _pools = new Dictionary<Pool, Queue<GameObject>>();
  36.  
  37.             foreach (var objectPool in _poolList)
  38.             {
  39.                 _pools.Add(objectPool.pool, CreatePool(objectPool));
  40.             }
  41.         }
  42.  
  43.         private Queue<GameObject> CreatePool(ObjectPool pool)
  44.         {
  45.             var objectPool = new Queue<GameObject>();
  46.  
  47.             Transform poolParent = CreatePoolParent(pool.pool);
  48.  
  49.             for (int j = 0; j < pool.size; j++)
  50.             {
  51.                 GameObject poolObject = InstantiateObject(pool.prefab);
  52.  
  53.                 poolObject.SetActive(false);
  54.  
  55.                 poolObject.transform.SetParent(poolParent);
  56.  
  57.                 objectPool.Enqueue(poolObject);
  58.             }
  59.  
  60.             return objectPool;
  61.         }
  62.  
  63.         private GameObject InstantiateObject(GameObject prefab)
  64.         {
  65.             return Instantiate(prefab);
  66.         }
  67.  
  68.         private Transform CreatePoolParent(Pool pool)
  69.         {
  70.             GameObject poolParentObj = new GameObject(pool.ToString());
  71.  
  72.             poolParentObj.transform.SetParent(_transform);
  73.  
  74.             return poolParentObj.transform;
  75.         }
  76.  
  77.         #endregion
  78.  
  79.         #region Spawn
  80.  
  81.         public GameObject Spawn(Pool pool) => Spawn(pool, Vector3.zero, Quaternion.identity);
  82.  
  83.         public GameObject Spawn(Pool pool, Vector3 position) => Spawn(pool, position, Quaternion.identity);
  84.  
  85.         public GameObject Spawn(Pool pool, Vector3 position, Quaternion rotation)
  86.         {
  87.             if (_pools.ContainsKey(pool) == false)
  88.             {
  89.                 throw new ArgumentException("Pool '" + pool + "' does not exist.");
  90.             }
  91.  
  92.             GameObject poolObject = GetFromPool(pool);
  93.  
  94.             if (poolObject.activeSelf) // тут за умови, потім перевірити
  95.             {
  96.                 poolObject.SetActive(false);
  97.             }
  98.  
  99.             poolObject.transform.position = position;
  100.             poolObject.transform.rotation = rotation;
  101.  
  102.             poolObject.SetActive(true);
  103.  
  104.             _pools[pool].Enqueue(poolObject);
  105.  
  106.             return poolObject;
  107.         }
  108.  
  109.         private GameObject GetFromPool(Pool pool)
  110.         {
  111.             if (IsExpandable(pool) == false)
  112.             {
  113.                 return _pools[pool].Dequeue();
  114.             }
  115.  
  116.             if (TryGetFirstInactive(pool, out GameObject poolObject))
  117.             {
  118.                 return poolObject;
  119.             }
  120.  
  121.             return AddPoolObject(pool, GetPrefab(pool));
  122.         }
  123.  
  124.         private bool TryGetFirstInactive(Pool pool, out GameObject poolObject)
  125.         {
  126.             for (int i = 0; i < _pools[pool].Count; i++)
  127.             {
  128.                 GameObject possibleObject = _pools[pool].Dequeue();
  129.  
  130.                 if (possibleObject.activeSelf == false)
  131.                 {
  132.                     _pools[pool].Enqueue(possibleObject);
  133.                    
  134.                     poolObject = possibleObject;
  135.                     return true;
  136.                 }
  137.  
  138.                 _pools[pool].Enqueue(possibleObject);
  139.             }
  140.  
  141.             poolObject = null;
  142.             return false;
  143.         }
  144.  
  145.         private GameObject GetPrefab(Pool pool)
  146.         {
  147.             foreach (var objectPool in _poolList)
  148.             {
  149.                 if (objectPool.pool == pool)
  150.                 {
  151.                     return objectPool.prefab;
  152.                 }
  153.             }
  154.  
  155.             throw new ArgumentException("Pool '" + pool + "' does not exist.");
  156.         }
  157.  
  158.         private bool IsExpandable(Pool pool)
  159.         {
  160.             foreach (var objectPool in _poolList)
  161.             {
  162.                 if (objectPool.pool == pool)
  163.                 {
  164.                     return objectPool.autoExpand;
  165.                 }
  166.             }
  167.  
  168.             throw new ArgumentException("Pool '" + pool + "' does not exist.");
  169.         }
  170.  
  171.         private GameObject AddPoolObject(Pool pool, GameObject prefab)
  172.         {
  173.             GameObject newPoolObject = InstantiateObject(prefab);
  174.  
  175.             newPoolObject.transform.SetParent(GetPoolTransform(pool));
  176.  
  177.             return newPoolObject;
  178.         }
  179.  
  180.         #endregion
  181.  
  182.         #region Utils
  183.  
  184.         private void DisableAllObjects()
  185.         {
  186.             foreach (Transform poolParent in _transform)
  187.             {
  188.                 foreach (Transform poolObject in poolParent)
  189.                 {
  190.                     poolObject.gameObject.SetActive(false);
  191.                 }
  192.             }
  193.         }
  194.  
  195.         private void DisablePool(Pool pool)
  196.         {
  197.             foreach (Transform poolObject in GetPoolTransform(pool))
  198.             {
  199.                 poolObject.gameObject.SetActive(false);
  200.             }
  201.         }
  202.  
  203.         private Transform GetPoolTransform(Pool pool)
  204.         {
  205.             GameObject poolObject = _pools[pool].Dequeue();
  206.             _pools[pool].Enqueue(poolObject);
  207.  
  208.             return poolObject.transform.parent;
  209.         }
  210.  
  211.         #endregion
  212.  
  213.         [Serializable]
  214.         private class ObjectPool
  215.         {
  216.             public Pool pool;
  217.             public GameObject prefab;
  218.             public int size;
  219.             public bool autoExpand;
  220.         }
  221.     }
  222. }
  223.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement