141 lines
3.9 KiB
C#
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);
|
|
}
|
|
}
|