Skip to content

Instantly share code, notes, and snippets.

@GeorgiyRyaposov
Last active April 27, 2017 08:04
Show Gist options
  • Save GeorgiyRyaposov/377092f9b44f178fc40108c176fb901e to your computer and use it in GitHub Desktop.
Save GeorgiyRyaposov/377092f9b44f178fc40108c176fb901e to your computer and use it in GitHub Desktop.
Unity ObjectPool, pul to scene and set objects, or init from code: Prefab.CreatePool(..); Prefab.Spawn() - spawn object, gameObject.Recycle() - return to pool
using UnityEngine;
using System.Collections.Generic;
namespace Scripts.Common
{
public sealed class ObjectPool : MonoBehaviour
{
public enum StartupPoolMode { Awake, Start, CallManually };
[System.Serializable]
public class StartupPool
{
public int size;
public GameObject prefab;
}
static ObjectPool _instance;
static List<GameObject> tempList = new List<GameObject>();
Dictionary<GameObject, List<GameObject>> pooledObjects = new Dictionary<GameObject, List<GameObject>>();
Dictionary<GameObject, GameObject> spawnedObjects = new Dictionary<GameObject, GameObject>();
public StartupPoolMode startupPoolMode;
public StartupPool[] startupPools;
bool startupPoolsCreated;
void Awake()
{
_instance = this;
if (startupPoolMode == StartupPoolMode.Awake)
CreateStartupPools();
}
void Start()
{
if (startupPoolMode == StartupPoolMode.Start)
CreateStartupPools();
}
public static void CreateStartupPools()
{
if (!instance.startupPoolsCreated)
{
instance.startupPoolsCreated = true;
var pools = instance.startupPools;
if (pools != null && pools.Length > 0)
for (int i = 0; i < pools.Length; ++i)
CreatePool(pools[i].prefab, pools[i].size);
}
}
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))
{
var list = new List<GameObject>();
instance.pooledObjects.Add(prefab, list);
if (initialPoolSize > 0)
{
bool active = prefab.activeSelf;
prefab.SetActive(false);
Transform parent = instance.transform;
while (list.Count < initialPoolSize)
{
var obj = (GameObject)Object.Instantiate(prefab);
obj.transform.SetParent(parent);
// obj.transform.parent = parent;
list.Add(obj);
}
prefab.SetActive(active);
}
}
}
public void CreatePoolFromEditor(GameObject prefab, int initialPoolSize)
{
if (prefab == null)
return;
var pool = startupPools.FirstOrDefault(s => s.prefab == prefab || s.prefab == null);
if (pool == null)
{
var newSize = startupPools.Length + 1;
System.Array.Resize(ref startupPools, newSize);
startupPools[newSize - 1] = new StartupPool {size = initialPoolSize, prefab = prefab};
}
else
{
pool.size = initialPoolSize;
pool.prefab = prefab;
}
}
public static T Spawn<T>(T prefab, Transform parent, Vector3 position, Quaternion rotation) where T : Component
{
return Spawn(prefab.gameObject, parent, position, rotation).GetComponent<T>();
}
public static T Spawn<T>(T prefab, Vector3 position, Quaternion rotation) where T : Component
{
return Spawn(prefab.gameObject, null, position, rotation).GetComponent<T>();
}
public static T Spawn<T>(T prefab, Transform parent, Vector3 position) where T : Component
{
return Spawn(prefab.gameObject, parent, position, Quaternion.identity).GetComponent<T>();
}
public static T Spawn<T>(T prefab, Vector3 position) where T : Component
{
return Spawn(prefab.gameObject, null, position, Quaternion.identity).GetComponent<T>();
}
public static T Spawn<T>(T prefab, Transform parent) where T : Component
{
return Spawn(prefab.gameObject, parent, Vector3.zero, Quaternion.identity).GetComponent<T>();
}
public static T Spawn<T>(T prefab) where T : Component
{
return Spawn(prefab.gameObject, null, Vector3.zero, Quaternion.identity).GetComponent<T>();
}
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 == null && list.Count > 0)
{
obj = list[0];
list.RemoveAt(0);
}
if (obj != null)
{
trans = obj.transform;
trans.SetParent(parent);
// trans.parent = parent;
trans.localPosition = position;
trans.localRotation = rotation;
obj.SetActive(true);
instance.spawnedObjects.Add(obj, prefab);
return obj;
}
}
obj = (GameObject)Object.Instantiate(prefab);
trans = obj.transform;
trans.SetParent(parent);
//trans.parent = parent;
trans.localPosition = position;
trans.localRotation = rotation;
instance.spawnedObjects.Add(obj, prefab);
return obj;
}
else
{
obj = (GameObject)Object.Instantiate(prefab);
trans = obj.GetComponent<Transform>();
trans.SetParent(parent);
// trans.parent = parent;
trans.localPosition = position;
trans.localRotation = rotation;
return obj;
}
}
public static GameObject Spawn(GameObject prefab, Transform parent, Vector3 position)
{
return Spawn(prefab, parent, position, Quaternion.identity);
}
public static GameObject Spawn(GameObject prefab, Vector3 position, Quaternion rotation)
{
return Spawn(prefab, null, position, rotation);
}
public static GameObject Spawn(GameObject prefab, Transform parent)
{
return Spawn(prefab, parent, Vector3.zero, Quaternion.identity);
}
public static GameObject Spawn(GameObject prefab, Vector3 position)
{
return Spawn(prefab, null, position, Quaternion.identity);
}
public static GameObject Spawn(GameObject prefab)
{
return Spawn(prefab, null, Vector3.zero, Quaternion.identity);
}
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
Object.Destroy(obj);
}
static void Recycle(GameObject obj, GameObject prefab)
{
instance.pooledObjects[prefab].Add(obj);
instance.spawnedObjects.Remove(obj);
if (obj != null)
{
obj.transform.SetParent(instance.transform);
//obj.transform.parent = instance.transform;
obj.SetActive(false);
}
}
public static void RecycleAll<T>(T prefab) where T : Component
{
RecycleAll(prefab.gameObject);
}
public static void RecycleAll(GameObject prefab)
{
foreach (var item in instance.spawnedObjects)
if (item.Value == prefab)
tempList.Add(item.Key);
var tempListCount = tempList.Count;
for (int i = 0; i < tempListCount; ++i)
Recycle(tempList[i]);
tempList.Clear();
}
public static void RecycleAll()
{
tempList.AddRange(instance.spawnedObjects.Keys);
for (int i = 0; i < tempList.Count; ++i)
Recycle(tempList[i]);
tempList.Clear();
}
public static bool IsSpawned(GameObject obj)
{
return instance.spawnedObjects.ContainsKey(obj);
}
public static int CountPooled<T>(T prefab) where T : Component
{
return CountPooled(prefab.gameObject);
}
public static int CountPooled(GameObject prefab)
{
List<GameObject> list;
if (instance.pooledObjects.TryGetValue(prefab, out list))
return list.Count;
return 0;
}
public static int CountSpawned<T>(T prefab) where T : Component
{
return CountSpawned(prefab.gameObject);
}
public static int CountSpawned(GameObject prefab)
{
int count = 0;
foreach (var instancePrefab in instance.spawnedObjects.Values)
if (prefab == instancePrefab)
++count;
return count;
}
public static int CountAllPooled()
{
int count = 0;
foreach (var list in instance.pooledObjects.Values)
count += list.Count;
return count;
}
public static List<GameObject> GetPooled(GameObject prefab, List<GameObject> list, bool appendList)
{
if (list == null)
list = new List<GameObject>();
if (!appendList)
list.Clear();
List<GameObject> pooled;
if (instance.pooledObjects.TryGetValue(prefab, out pooled))
list.AddRange(pooled);
return list;
}
public static List<T> GetPooled<T>(T prefab, List<T> list, bool appendList) where T : Component
{
if (list == null)
list = new List<T>();
if (!appendList)
list.Clear();
List<GameObject> pooled;
if (instance.pooledObjects.TryGetValue(prefab.gameObject, out pooled))
for (int i = 0; i < pooled.Count; ++i)
list.Add(pooled[i].GetComponent<T>());
return list;
}
public static List<GameObject> GetSpawned(GameObject prefab, List<GameObject> list, bool appendList)
{
if (list == null)
list = new List<GameObject>();
if (!appendList)
list.Clear();
foreach (var item in instance.spawnedObjects)
if (item.Value == prefab)
list.Add(item.Key);
return list;
}
public static List<T> GetSpawned<T>(T prefab, List<T> list, bool appendList) where T : Component
{
if (list == null)
list = new List<T>();
if (!appendList)
list.Clear();
var prefabObj = prefab.gameObject;
foreach (var item in instance.spawnedObjects)
if (item.Value == prefabObj)
list.Add(item.Key.GetComponent<T>());
return list;
}
public static void DestroyPooled(GameObject prefab)
{
List<GameObject> pooled;
if (instance.pooledObjects.TryGetValue(prefab, out pooled))
{
for (int i = 0; i < pooled.Count; ++i)
GameObject.Destroy(pooled[i]);
pooled.Clear();
}
}
public static void DestroyPooled<T>(T prefab) where T : Component
{
DestroyPooled(prefab.gameObject);
}
public static void DestroyAll(GameObject prefab)
{
RecycleAll(prefab);
DestroyPooled(prefab);
}
public static void DestroyAll<T>(T prefab) where T : Component
{
DestroyAll(prefab.gameObject);
}
public static ObjectPool instance
{
get
{
if (_instance != null)
return _instance;
_instance = Object.FindObjectOfType<ObjectPool>();
if (_instance != null)
return _instance;
var obj = new GameObject("ObjectPool");
obj.transform.localPosition = Vector3.zero;
obj.transform.localRotation = Quaternion.identity;
obj.transform.localScale = Vector3.one;
_instance = obj.AddComponent<ObjectPool>();
return _instance;
}
}
}
public static class ObjectPoolExtensions
{
public static void CreatePool<T>(this T prefab) where T : Component
{
ObjectPool.CreatePool(prefab, 0);
}
public static void CreatePool<T>(this T prefab, int initialPoolSize) where T : Component
{
ObjectPool.CreatePool(prefab, initialPoolSize);
}
public static void CreatePool(this GameObject prefab)
{
ObjectPool.CreatePool(prefab, 0);
}
public static void CreatePool(this GameObject prefab, int initialPoolSize)
{
ObjectPool.CreatePool(prefab, initialPoolSize);
}
public static T Spawn<T>(this T prefab, Transform parent, Vector3 position, Quaternion rotation) where T : Component
{
return ObjectPool.Spawn(prefab, parent, position, rotation);
}
public static T Spawn<T>(this T prefab, Vector3 position, Quaternion rotation) where T : Component
{
return ObjectPool.Spawn(prefab, null, position, rotation);
}
public static T Spawn<T>(this T prefab, Transform parent, Vector3 position) where T : Component
{
return ObjectPool.Spawn(prefab, parent, position, Quaternion.identity);
}
public static T Spawn<T>(this T prefab, Vector3 position) where T : Component
{
return ObjectPool.Spawn(prefab, null, position, Quaternion.identity);
}
public static T Spawn<T>(this T prefab, Transform parent) where T : Component
{
return ObjectPool.Spawn(prefab, parent, Vector3.zero, Quaternion.identity);
}
public static T Spawn<T>(this T prefab) where T : Component
{
return ObjectPool.Spawn(prefab, null, Vector3.zero, Quaternion.identity);
}
public static GameObject Spawn(this GameObject prefab, Transform parent, Vector3 position, Quaternion rotation)
{
return ObjectPool.Spawn(prefab, parent, position, rotation);
}
public static GameObject Spawn(this GameObject prefab, Vector3 position, Quaternion rotation)
{
return ObjectPool.Spawn(prefab, null, position, rotation);
}
public static GameObject Spawn(this GameObject prefab, Transform parent, Vector3 position)
{
return ObjectPool.Spawn(prefab, parent, position, Quaternion.identity);
}
public static GameObject Spawn(this GameObject prefab, Vector3 position)
{
return ObjectPool.Spawn(prefab, null, position, Quaternion.identity);
}
public static GameObject Spawn(this GameObject prefab, Transform parent)
{
return ObjectPool.Spawn(prefab, parent, Vector3.zero, Quaternion.identity);
}
public static GameObject Spawn(this GameObject prefab)
{
return ObjectPool.Spawn(prefab, null, Vector3.zero, Quaternion.identity);
}
public static void Recycle<T>(this T obj) where T : Component
{
ObjectPool.Recycle(obj);
}
public static void Recycle(this GameObject obj)
{
ObjectPool.Recycle(obj);
}
public static void RecycleAll<T>(this T prefab) where T : Component
{
ObjectPool.RecycleAll(prefab);
}
public static void RecycleAll(this GameObject prefab)
{
ObjectPool.RecycleAll(prefab);
}
public static int CountPooled<T>(this T prefab) where T : Component
{
return ObjectPool.CountPooled(prefab);
}
public static int CountPooled(this GameObject prefab)
{
return ObjectPool.CountPooled(prefab);
}
public static int CountSpawned<T>(this T prefab) where T : Component
{
return ObjectPool.CountSpawned(prefab);
}
public static int CountSpawned(this GameObject prefab)
{
return ObjectPool.CountSpawned(prefab);
}
public static List<GameObject> GetSpawned(this GameObject prefab, List<GameObject> list, bool appendList)
{
return ObjectPool.GetSpawned(prefab, list, appendList);
}
public static List<GameObject> GetSpawned(this GameObject prefab, List<GameObject> list)
{
return ObjectPool.GetSpawned(prefab, list, false);
}
public static List<GameObject> GetSpawned(this GameObject prefab)
{
return ObjectPool.GetSpawned(prefab, null, false);
}
public static List<T> GetSpawned<T>(this T prefab, List<T> list, bool appendList) where T : Component
{
return ObjectPool.GetSpawned(prefab, list, appendList);
}
public static List<T> GetSpawned<T>(this T prefab, List<T> list) where T : Component
{
return ObjectPool.GetSpawned(prefab, list, false);
}
public static List<T> GetSpawned<T>(this T prefab) where T : Component
{
return ObjectPool.GetSpawned(prefab, null, false);
}
public static List<GameObject> GetPooled(this GameObject prefab, List<GameObject> list, bool appendList)
{
return ObjectPool.GetPooled(prefab, list, appendList);
}
public static List<GameObject> GetPooled(this GameObject prefab, List<GameObject> list)
{
return ObjectPool.GetPooled(prefab, list, false);
}
public static List<GameObject> GetPooled(this GameObject prefab)
{
return ObjectPool.GetPooled(prefab, null, false);
}
public static List<T> GetPooled<T>(this T prefab, List<T> list, bool appendList) where T : Component
{
return ObjectPool.GetPooled(prefab, list, appendList);
}
public static List<T> GetPooled<T>(this T prefab, List<T> list) where T : Component
{
return ObjectPool.GetPooled(prefab, list, false);
}
public static List<T> GetPooled<T>(this T prefab) where T : Component
{
return ObjectPool.GetPooled(prefab, null, false);
}
public static void DestroyPooled(this GameObject prefab)
{
ObjectPool.DestroyPooled(prefab);
}
public static void DestroyPooled<T>(this T prefab) where T : Component
{
ObjectPool.DestroyPooled(prefab.gameObject);
}
public static void DestroyAll(this GameObject prefab)
{
ObjectPool.DestroyAll(prefab);
}
public static void DestroyAll<T>(this T prefab) where T : Component
{
ObjectPool.DestroyAll(prefab.gameObject);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment