Created
March 7, 2022 07:47
-
-
Save SabinT/2c4ecada95aa9e94572c805ba9d2d21a to your computer and use it in GitHub Desktop.
Generic Object Pooling in Unity 3D
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
using System; | |
using System.Collections.Generic; | |
using UnityEngine; | |
namespace Lumic.Structure.Procedural | |
{ | |
public class MeshPool : ObjectPool<Mesh> | |
{ | |
protected override Mesh CreateNew() | |
{ | |
return new Mesh(); | |
} | |
protected override void Deactivate(Mesh item) | |
{ | |
return; | |
} | |
} | |
public class ObjectPool<T> where T : UnityEngine.Object | |
{ | |
private readonly Dictionary<T, int> activeSet = new Dictionary<T, int>(); | |
private readonly List<T> activePool = new List<T>(); | |
private readonly Queue<T> freePool = new Queue<T>(); | |
public int GetTotalCount() | |
{ | |
return this.activePool.Count + this.freePool.Count; | |
} | |
public int GetActiveCount() | |
{ | |
return this.activePool.Count; | |
} | |
public T CreateOrGetFromPool(int limit) | |
{ | |
// Add to pool if below capacity and no recyclable items | |
if (this.freePool.Count == 0 && this.activePool.Count < limit) | |
{ | |
this.freePool.Enqueue(this.CreateNew()); | |
} | |
// Get from pool | |
if (this.freePool.Count > 0) | |
{ | |
T item = this.freePool.Dequeue(); | |
// Check is item is still alive | |
if ((item as UnityEngine.Object) == null) | |
{ | |
// Create new one, get rid of unusable reference | |
item = this.CreateNew(); | |
} | |
this.activeSet[item] = this.activePool.Count; | |
this.activePool.Add(item); | |
return item; | |
} | |
return default; | |
} | |
public void ReturnToPool(T item) | |
{ | |
this.Deactivate(item); | |
if (this.activeSet.TryGetValue(item, out int currentIndex)) | |
{ | |
int lastIndex = this.activePool.Count - 1; | |
T lastElement = this.activePool[lastIndex]; | |
this.activePool[currentIndex] = lastElement; | |
this.activeSet[lastElement] = currentIndex; | |
this.activePool.RemoveAt(lastIndex); | |
this.activeSet.Remove(item); | |
this.freePool.Enqueue(item); | |
} | |
} | |
protected virtual T CreateNew() | |
{ | |
throw new NotImplementedException(); | |
} | |
protected virtual void Deactivate(T item) | |
{ | |
throw new NotImplementedException(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment