LD50/Assets/Scripts/PoolManager.cs
2022-04-05 02:09:50 +02:00

141 lines
3.9 KiB
C#

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<GameObject> remainingGameObjects = new Queue<GameObject>();
private HashSet<GameObject> instancedGameObjects = new HashSet<GameObject>();
public Pool(InstantiationPrefabSettings settings)
{
this.settings = settings;
}
public void Init()
{
remainingGameObjects = new Queue<GameObject>();
instancedGameObjects = new HashSet<GameObject>();
for(int n=0;n<settings.minCount;n++)
{
GameObject g = GameObject.Instantiate(settings.prefab, Vector3.zero, Quaternion.identity);
g.SetActive(false);
g.transform.parent = PoolManager.Instance.transform;
remainingGameObjects.Enqueue(g);
}
}
public GameObject GetInstance()
{
int remainingInstanceCount = remainingGameObjects.Count;
int remainingInstantiableCount = settings.maxCount - (remainingGameObjects.Count + instancedGameObjects.Count);
GameObject instance = null;
if(remainingInstanceCount > 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<PoolableMonoBehaviour>();
if(poolableMonoBehaviour != null)
{
poolableMonoBehaviour.OnRetrieve();
}
}
return instance;
}
public void ReturnInstance(GameObject gameObj)
{
int remainingInstanceCount = remainingGameObjects.Count;
if(remainingInstanceCount < settings.minCount)
{
PoolableMonoBehaviour poolableMonoBehaviour = gameObj.GetComponent<PoolableMonoBehaviour>();
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<GameObject, Pool> pools = new Dictionary<GameObject, Pool>();
private Dictionary<GameObject, GameObject> instanceToPrefabDict = new Dictionary<GameObject, GameObject>();
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);
}
}