Skip to content

Instantly share code, notes, and snippets.

@Streamweaver
Last active February 7, 2020 04:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Streamweaver/b9164c538e277b9ecf85e71d84e59162 to your computer and use it in GitHub Desktop.
Save Streamweaver/b9164c538e277b9ecf85e71d84e59162 to your computer and use it in GitHub Desktop.
This is an objectpool class I derived from the SimplePool.cs class created by Quill18. It's refactored a bit for simplification and removing redundant calls. In particular this is a static class that can be called anywhere and allows the object to destroy itself.
using UnityEngine;
using System.Collections.Generic;
// Original adopted from Quill18's SimplePool Example. Storing here as an example.
// Example of using with a spawn manager in Gist
// https://gist.github.com/Streamweaver/1567f1c5c450d3ec2deb0efedce31ddf
// See below for a pooled particle system extension of this.
public static class ObjectPool
{
const int DEFAULT_POOL_SIZE = 3;
class PoolMember : MonoBehaviour
{
public Pool myPool;
}
class Pool
{
int nextId = 1;
Queue<GameObject> inactive;
GameObject prefab;
private int _active;
public Pool(GameObject prefab, int initialQty)
{
this.prefab = prefab;
inactive = new Queue<GameObject>(initialQty);
}
public GameObject DequeueOrSpawn(Vector3 pos, Quaternion rot, GameObject parent = null)
{
GameObject spawned;
if (inactive.Count < 1)
{
spawned = (GameObject)GameObject.Instantiate(prefab, pos, rot);
spawned.name = prefab.name + " (" + (nextId++) + ")";
if (parent != null)
{
spawned.transform.SetParent(parent.transform);
}
spawned.AddComponent<PoolMember>().myPool = this;
} else
{
spawned = inactive.Dequeue();
}
spawned.transform.position = pos;
spawned.transform.rotation = rot;
spawned.SetActive(true);
_active++;
return spawned;
}
// Return an object to the inactive pool.
public void Despawn(GameObject obj)
{
obj.SetActive(false);
_active--;
inactive.Enqueue(obj);
}
public int NumberActive()
{
return _active;
}
}
// All of our pools
static Dictionary<GameObject, Pool> pools;
static void CreatePool(GameObject prefab = null, int qty = DEFAULT_POOL_SIZE)
{
if (pools == null)
{
pools = new Dictionary<GameObject, Pool>();
}
if (prefab != null && !pools.ContainsKey(prefab))
{
pools[prefab] = new Pool(prefab, qty);
}
}
static public void Preload(GameObject prefab, int qty = 1, GameObject parent = null)
{
CreatePool(prefab, qty); // Create the pool if it doesn't exist.
// Make an array to grab the objects we're about to pre-spawn.
GameObject[] obs = new GameObject[qty];
for (int i = 0; i < qty; i++)
{
obs[i] = Spawn(prefab, Vector3.zero, Quaternion.identity, parent);
}
//// Now despawn them all.
for (int i = 0; i < qty; i++)
{
Despawn(obs[i]);
}
}
static public GameObject Spawn(GameObject prefab, Vector3 pos, Quaternion rot, GameObject parent = null)
{
CreatePool(prefab);
return pools[prefab].DequeueOrSpawn(pos, rot, parent);
}
static public void Despawn(GameObject obj)
{
PoolMember pm = obj.GetComponent<PoolMember>();
if (pm == null)
{
Debug.Log("Object '" + obj.name + "' wasn't spawned from a pool. Destroying it instead.");
GameObject.Destroy(obj);
}
else
{
pm.myPool.Despawn(obj);
}
}
static public int NumberActive(GameObject prefab)
{
if (pools.ContainsKey(prefab))
{
return pools[prefab].NumberActive();
}
return 0;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(ParticleSystem))]
public class PooledParticleSystem : MonoBehaviour
{
ParticleSystem _ps = null;
// Start is called before the first frame update
void Awake()
{
_ps = GetComponent<ParticleSystem>();
}
// Update is called once per frame
void Update()
{
}
private void OnParticleSystemStopped()
{
ObjectPool.Despawn(gameObject);
}
private void OnEnable()
{
_ps.Play();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment