152 lines
No EOL
4.7 KiB
C#
152 lines
No EOL
4.7 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Pooling {
|
|
public class Pooler : MonoBehaviour {
|
|
private static Pooler _instance;
|
|
|
|
public static Pooler Instance {
|
|
get {
|
|
if (_instance != null)
|
|
return _instance;
|
|
|
|
_instance = FindObjectOfType<Pooler>();
|
|
if (_instance != null)
|
|
return _instance;
|
|
|
|
GameObject obj = new("[Object Pool]");
|
|
_instance = obj.AddComponent<Pooler>();
|
|
return _instance;
|
|
}
|
|
}
|
|
|
|
private static List<GameObject> _tempList = new();
|
|
|
|
private Dictionary<GameObject, List<GameObject>> _pooledObjects = new();
|
|
private Dictionary<GameObject, GameObject> _spawnedObjects = new();
|
|
|
|
public static void CreatePool<T>(T prefab, int initialPoolSize) where T : Component {
|
|
CreatePool(prefab.gameObject, initialPoolSize);
|
|
}
|
|
|
|
public static void CreatePool(GameObject prefab, int initialPoolSize) {
|
|
if (prefab == null || Instance._pooledObjects.ContainsKey(prefab))
|
|
return;
|
|
|
|
List<GameObject> list = new();
|
|
Instance._pooledObjects.Add(prefab, list);
|
|
|
|
if (initialPoolSize <= 0) return;
|
|
|
|
bool active = prefab.activeSelf;
|
|
prefab.SetActive(false);
|
|
Transform parent = Instance.transform;
|
|
while (list.Count < initialPoolSize) {
|
|
GameObject obj = Instantiate(prefab, parent);
|
|
list.Add(obj);
|
|
}
|
|
prefab.SetActive(active);
|
|
}
|
|
|
|
public static T Spawn<T>(T prefab, Transform parent, Vector3 position, Quaternion rotation)
|
|
where T : Component =>
|
|
Spawn(prefab.gameObject, parent, position, rotation).GetComponent<T>();
|
|
|
|
public static T Spawn<T>(T prefab, Vector3 position, Quaternion rotation) where T : Component =>
|
|
Spawn(prefab.gameObject, null, position, rotation).GetComponent<T>();
|
|
|
|
public static T Spawn<T>(T prefab, Transform parent, Vector3 position) where T : Component =>
|
|
Spawn(prefab.gameObject, parent, position, Quaternion.identity).GetComponent<T>();
|
|
|
|
public static T Spawn<T>(T prefab, Vector3 position) where T : Component =>
|
|
Spawn(prefab.gameObject, null, position, Quaternion.identity).GetComponent<T>();
|
|
|
|
public static T Spawn<T>(T prefab, Transform parent) where T : Component =>
|
|
Spawn(prefab.gameObject, parent, Vector3.zero, Quaternion.identity).GetComponent<T>();
|
|
|
|
public static T Spawn<T>(T prefab) where T : Component =>
|
|
Spawn(prefab.gameObject, null, Vector3.zero, Quaternion.identity).GetComponent<T>();
|
|
|
|
public static GameObject Spawn(GameObject prefab, Transform parent, Vector3 position) =>
|
|
Spawn(prefab, parent, position, Quaternion.identity);
|
|
|
|
public static GameObject Spawn(GameObject prefab, Vector3 position, Quaternion rotation) =>
|
|
Spawn(prefab, null, position, rotation);
|
|
|
|
public static GameObject Spawn(GameObject prefab, Transform parent) =>
|
|
Spawn(prefab, parent, Vector3.zero, Quaternion.identity);
|
|
|
|
public static GameObject Spawn(GameObject prefab, Vector3 position) =>
|
|
Spawn(prefab, null, position, Quaternion.identity);
|
|
|
|
public static GameObject Spawn(GameObject prefab) =>
|
|
Spawn(prefab, null, Vector3.zero, Quaternion.identity);
|
|
|
|
public static GameObject Spawn(GameObject prefab, Transform parent, Vector3 position, Quaternion rotation) {
|
|
List<GameObject> list;
|
|
Transform trans;
|
|
GameObject obj;
|
|
|
|
if (Instance._pooledObjects.TryGetValue(prefab, out list)) {
|
|
obj = null;
|
|
if (list.Count > 0) {
|
|
while (!obj && list.Count > 0) {
|
|
obj = list[0];
|
|
list.RemoveAt(0);
|
|
}
|
|
if (obj != null) {
|
|
trans = obj.transform;
|
|
trans.parent = parent;
|
|
trans.localPosition = position;
|
|
trans.localRotation = rotation;
|
|
obj.SetActive(true);
|
|
Instance._spawnedObjects.Add(obj, prefab);
|
|
TryCallPooledObject(obj);
|
|
return obj;
|
|
}
|
|
}
|
|
|
|
obj = Instantiate(prefab);
|
|
trans = obj.transform;
|
|
trans.parent = parent;
|
|
trans.localPosition = position;
|
|
trans.localRotation = rotation;
|
|
Instance._spawnedObjects.Add(obj, prefab);
|
|
TryCallPooledObject(obj);
|
|
return obj;
|
|
}
|
|
|
|
obj = Instantiate(prefab);
|
|
trans = obj.transform;
|
|
trans.parent = parent;
|
|
trans.localPosition = position;
|
|
trans.localRotation = rotation;
|
|
TryCallPooledObject(obj);
|
|
return obj;
|
|
}
|
|
|
|
private static void TryCallPooledObject(GameObject obj) {
|
|
if(obj.TryGetComponent(out IPooledObject pooledObject))
|
|
pooledObject.OnObjectSpawn();
|
|
}
|
|
|
|
public static void Recycle<T>(T obj) where T : Component {
|
|
Recycle(obj.gameObject);
|
|
}
|
|
|
|
public static void Recycle(GameObject obj) {
|
|
GameObject prefab;
|
|
if (Instance._spawnedObjects.TryGetValue(obj, out prefab))
|
|
Recycle(obj, prefab);
|
|
else
|
|
Destroy(obj);
|
|
}
|
|
|
|
private static void Recycle(GameObject obj, GameObject prefab) {
|
|
Instance._pooledObjects[prefab].Add(obj);
|
|
Instance._spawnedObjects.Remove(obj);
|
|
obj.transform.parent = Instance.transform;
|
|
obj.SetActive(false);
|
|
}
|
|
}
|
|
} |