Last active
February 7, 2020 04:23
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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