Skip to content

Instantly share code, notes, and snippets.

@Minimally
Created May 8, 2014 22:27
Show Gist options
  • Save Minimally/37d49caf2e46723169ff to your computer and use it in GitHub Desktop.
Save Minimally/37d49caf2e46723169ff to your computer and use it in GitHub Desktop.
Unity3d pooling using Extensions on GameObject.
using UnityEngine;
using System.Collections.Generic;
public static class PoolItExtension
{
private static Transform pool;
private static Transform Pool { get { return (pool == null) ? pool = new GameObject(" Pool It!").transform : pool; } }
private static Dictionary<GameObject, List<GameObject>> container = new Dictionary<GameObject, List<GameObject>>();
#region Pooling Via GameObject Extensions
/// <summary> Pools it! Uses this GameObject as the prefab for a pool. /// </summary>
/// <param name="prefab">Prefab.</param>
/// <param name="count">Amount to Instantiate as a start.</param>
public static void PoolIt(this GameObject prefab, int count)
{
PoolOpen(prefab, count);
}
/// <summary> Spawns it! Returns a pooled copy of this GameObject. /// </summary>
/// <returns>The it.</returns>
/// <param name="prefab">Prefab.</param>
public static GameObject SpawnAndParentIt(this GameObject prefab)
{
return SpawnAndParentIt(prefab, null);
}
/// <summary> Spawns it and Parents it! Returns a pooled copy of this GameObject parented to the sent in parent GameObject. /// </summary>
/// <returns>The and parent it.</returns>
/// <param name="prefab">Prefab.</param>
/// <param name="parent">Parent.</param>
public static GameObject SpawnAndParentIt(this GameObject prefab, GameObject parent, bool includeLabelWhenParenting = false)
{
return PoolItExtension.Instantiate(prefab, parent, includeLabelWhenParenting);
}
/// <summary> Recycle it! This simply sets the GameObject as inactive. /// </summary>
/// <param name="clone">Clone.</param>
public static void RecycleIt(this GameObject clone)
{
PoolItExtension.Destroy(clone);
}
#endregion
#region Pooling
/// <summary> Open It! Creates a new pool for the sent in Prefab /// </summary>
/// <param name="prefab">Prefab.</param>
public static void PoolOpen(GameObject prefab, int count)
{
if (!container.ContainsKey(prefab))
{
container.Add(prefab, new List<GameObject>());
for (int i = 0; i < count; i++)
CloneMake(prefab);
}
}
/// <summary> Close It! Permanently delete pooled GameObjects. </summary>
/// <param name="prefab">Prefab.</param>
public static void PoolClose(GameObject prefab)
{
if (!container.ContainsKey(prefab))
return;
for (int i = container[prefab].Count - 1; i >= 0; i--)
{
GameObject cur = container[prefab][i];
container.Remove(container[prefab][i]);
Destroy(cur);
}
}
/// <summary> Instantiate it! Returns the first inactive instance of the prefab from the pool or makes one. /// </summary>
/// <param name="prefab">Prefab.</param>
public static GameObject Instantiate(GameObject prefab)
{
return Instantiate(prefab, null);
}
/// <summary> Instantiate it! Returns the first inactive instance of the prefab from the pool or makes one. /// </summary>
/// <param name="prefab">Prefab.</param>
public static GameObject Instantiate(GameObject prefab, GameObject parent, bool includeLabelWhenParenting = false)
{
GameObject result = null;
if (container.ContainsKey(prefab))
{
// Find the first inactive in the container
for (int i = 0; i < container[prefab].Count; i++)
{
if (container[prefab][i].activeSelf == false)
{
result = container[prefab][i];
break;
}
}
// If nada was found, make an instance
result = result ?? CloneMake(prefab);
}
// Create a pool for the prefab because there isn't one
else
{
PoolOpen(prefab, 0);
result = CloneMake(prefab);
container[prefab].Add(result);
}
if (result != null && parent != null)
{
Transform resultTransform = result.transform;
resultTransform.parent = parent.transform;
resultTransform.localPosition = Vector3.zero;
resultTransform.localRotation = Quaternion.identity;
resultTransform.localScale = Vector3.one;
if (includeLabelWhenParenting) result.layer = parent.layer;
}
result.SetActive(true);
return result;
}
/// <summary> Destroy it! Deactivates the sent in GameObject and sends it back into the pool. /// </summary>
/// <param name="clone">Clone.</param>
public static void Destroy(GameObject clone)
{
clone.transform.parent = Pool;
clone.SetActive(false);
}
#endregion
#region Various
private static GameObject CloneMake(GameObject prefab)
{
GameObject result = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity) as GameObject;
container[prefab].Add(result);
result.transform.parent = Pool;
return result;
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment