Last active
June 8, 2021 12:19
-
-
Save ecmjohnson/ac0fc5c1160c975551ce16a31c457b28 to your computer and use it in GitHub Desktop.
Unity object pooling script
This file contains 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
/** | |
* This class implements the object pool pattern: | |
* | |
* It can be used for creating objects exactly as if using Unity's `Instantiate` call. Simply | |
* call `AcquireObject` with a prefab and an instance of that object will be returned, either | |
* recycled from the pool or allocated if the pool is empty. | |
* | |
* It is the responsibility of the object to set itself inactive with `SetActive(false)` at | |
* lifetime end. This is how objects are recycled by the pool. | |
* | |
* This class also provides the previous `DynamicRegister` functionality. This ensures that all | |
* GameObjects created during runtime fall under the `_Dynamic` root object. This helps organize | |
* the scene during debugging. | |
*/ | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public static class ObjectPool | |
{ | |
/** Public static functions **/ | |
/** | |
* Returns an object from the pool. Client is responsible for all other initialization. | |
*/ | |
public static GameObject AcquireObject(GameObject prefab) | |
{ | |
string key = SanitizeName(prefab.name); | |
if (!_objects.ContainsKey(key)) { | |
GenerateObject(prefab); | |
} else if (_objects[key].Count < 1) { | |
GenerateObject(prefab); | |
} | |
GameObject go = _objects[key].Find(e => !e.activeSelf); | |
if (go == null) { | |
go = GenerateObject(prefab); | |
} | |
return go; | |
} | |
/** | |
* Returns an object from the pool and sets the provided location and orientation. | |
*/ | |
public static GameObject AcquireObject(GameObject prefab, Vector2 location, Quaternion quat) | |
{ | |
GameObject go = AcquireObject(prefab); | |
go.transform.SetPositionAndRotation(location, quat); | |
return go; | |
} | |
/** | |
* Adds the requested number of objects to the pool. | |
*/ | |
public static void AddToPool(GameObject prefab, uint number) | |
{ | |
for (uint i = 0; i < number; i++) { | |
GenerateObject(prefab); | |
} | |
} | |
/** Private constants **/ | |
private const string DYNAMIC_NAME = "_Dynamic"; | |
/** Private variables **/ | |
private static Dictionary<string, List<GameObject>> _objects = new Dictionary<string, List<GameObject>>(); | |
private static GameObject _dynamic = null; | |
/** Private functions **/ | |
private static GameObject GenerateObject(GameObject prefab) | |
{ | |
GameObject created = GameObject.Instantiate(prefab); | |
created.SetActive(false); | |
string key = SanitizeName(created.name); | |
if (_objects.ContainsKey(key)) { | |
_objects[key].Add(created); | |
} else { | |
List<GameObject> list = new List<GameObject>(); | |
list.Add(created); | |
_objects.Add(key, list); | |
} | |
RegisterDynamic(ref created); | |
return created; | |
} | |
private static void RegisterDynamic(ref GameObject toRegister) | |
{ | |
if (_dynamic == null) { | |
_dynamic = GameObject.Find(DYNAMIC_NAME); | |
if (_dynamic == null) { | |
_dynamic = new GameObject(DYNAMIC_NAME); | |
} | |
} | |
if (_dynamic != null) { | |
toRegister.transform.parent = _dynamic.transform; | |
} | |
} | |
private static string SanitizeName(string name) | |
{ | |
return name.Replace("(Clone)", ""); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment