I've written a generic object pooling class that should be able to pool instances of any class that inherits from UnityEngine.Object without making any changes to that class. I've also written some classes that simplify pooling for commonly used object types like GameObjects and MonoBehaviours, and an interface so that they can be used interchangeably after construction and new classes can be written easily. I'd like to put it on the Unify Community Wiki, but first I want to make sure that the code is as useful, concise and intuitive as it can be. Suggestions welcome.
sample use of GameObjectPool:
Code:
goPool.Return(poolie);
sample use of GenericPool with anonymous methods:
Code:
sample use of GenericPool with an object to copy and method references:
Code:
IPool<CustomType> customPool = new GenericPool<CustomType> (customInstance, 80, Reset, Disable, Enable);
the code itself:
Code:
using UnityEngine; using System.Collections; using System.Collections.Generic; using System; using System.Linq; public interface IPool<T> { T Get(); void Return (T objectToPool); } public class GenericPool<T> : UnityEngine.Object, IPool<T> where T : UnityEngine.Object { protected HashSet<T> pool; protected T original; //if provided, all pool objects will be copies of this object protected Func<T> Constructor; //creates the pool objects from a given method. protected Action<T> Recycler; //called on each object when it is returned to the pool. it should reset all changed values. protected Action<T> Disabler; //called on each object when it is returned to the pool. it should "hide" the object from anything that might try to //interact with it, or keep the object from doing anything. protected Action<T> Activator; //called on each object when it is gotten from the pool. it should undo whatever the disabler did so that the object //is able to act freely again. //create a pool containing copies of a given object. public GenericPool (T original, int initialSize, Action<T> Recycler, Action<T> Disabler, Action<T> Activator) { this.original = original; this.Recycler = Recycler; this.Disabler = Disabler; this.Activator = Activator; for (int i = 0; i < initialSize; i++) { } } //create a pool of objects built by a passed-in function. public GenericPool (Func<T> Constructor, int initialSize, Action<T> Recycler, Action<T> Disabler, Action<T> Activator) { this.Constructor = Constructor; this.Recycler = Recycler; this.Disabler = Disabler; this.Activator = Activator; for (int i = 0; i < initialSize; i++) { } } protected GenericPool () { } //creates a new instance of whatever object we're pooling protected virtual T MakeNew () { T copy; if (original != null) //if the pool was provided an original objec to copy, copy it { Disabler(copy); } else if (Constructor != null) //if a constructor was supplied instead, call it { copy = Constructor(); Disabler(copy); } else { copy = null; } return copy; } T IPool<T>.Get () { T unPooledObject; { unPooledObject = MakeNew(); } else { unPooledObject = pool.First(); } if (Activator != null) { Activator(unPooledObject); } return unPooledObject; } void IPool<T>.Return (T objectToPool) { if (Recycler != null) { Recycler(objectToPool); } if (Disabler != null) { Disabler(objectToPool); } } } } public class GameObjectPool : GenericPool<GameObject> { pool = new HashSet<GameObject>(); this.original = original; this.Recycler = Recycler; this.Disabler = Disable; this.Activator = Activate; for (int i = 0; i < initialSize; i++) { } } go.hideFlags = HideFlags.HideInHierarchy; } go.hideFlags = 0; } } protected GameObject attatchedObject; public ComponentPool (GameObject attatchedObject, int initialSize, Func<T> Constructor = null, Action<T> Recycler = null) { pool = new HashSet<T>(); this.attatchedObject = attatchedObject; this.Constructor = Constructor; this.Recycler = Recycler; for (int i = 0; i < initialSize; i++) { } } protected ComponentPool () { } protected override T MakeNew () { T copy; if (Constructor != null) { copy = Constructor(); } else { copy = attatchedObject.AddComponent<T>(); } return copy; } } public MonoBehaviourPool (GameObject attatchedObject, int initialSize, Func<T> Constructor = null, Action<T> Recycler = null) { pool = new HashSet<T>(); this.attatchedObject = attatchedObject; this.Constructor = Constructor; this.Recycler = Recycler; this.Disabler = Disable; this.Activator = Activate; for (int i = 0; i < initialSize; i++) { T copy = MakeNew(); copy.enabled = false; } } private void Activate (T behaviour) { behaviour.enabled = true; } private void Disable (T behaviour) { behaviour.enabled = false; } }

Reply With Quote