Skip to content

Instantly share code, notes, and snippets.

@bfollington
Last active January 26, 2021 03:07
Show Gist options
  • Save bfollington/0addf4cb1788bb884ae8fce0278b5a5a to your computer and use it in GitHub Desktop.
Save bfollington/0addf4cb1788bb884ae8fce0278b5a5a to your computer and use it in GitHub Desktop.
Simple object pooling solution
public static class ExampleUse {
public static void Example(ObjectPoolingSystem pool) {
pool.Get(ObjectPoolType.SelectFx, fx => {
fx.transform.position = new Vector3(1, 1, 1);
});
}
}
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
using Zenject;
public enum ObjectPoolType
{
AttackFx,
SelectFx,
DeathFx
}
/*
Object Pooling:
Something needs to hold the pool(s)
Get(poolName, initFn)
-> find inactive instance
-> mark as active
-> call initFn
Reset(this, poolName)
-> mark instance as inactive
*/
public class ObjectPoolingSystem : MonoBehaviour
{
private Dictionary<ObjectPoolType, List<GameObject>> _pools;
public GameObject AttackFx;
public GameObject SelectFx;
public GameObject DeathFx;
private DiContainer _ctx;
[Inject]
public void Inject(DiContainer ctx) {
_ctx = ctx;
}
// Start is called before the first frame update
void Start() {
Assert.IsNotNull(AttackFx);
Assert.IsNotNull(SelectFx);
Assert.IsNotNull(DeathFx);
transform.position = Vector3.zero;
_pools = new Dictionary<ObjectPoolType, List<GameObject>>();
InitPool(ObjectPoolType.SelectFx, SelectFx, 6);
InitPool(ObjectPoolType.AttackFx, AttackFx, 10);
InitPool(ObjectPoolType.DeathFx, DeathFx, 10);
}
private void InitPool(ObjectPoolType t, GameObject prefab, int count) {
Assert.IsNotNull(prefab);
Assert.IsTrue(count > 0);
var lst = new List<GameObject>();
for (var i = 0; i < count; i++) {
var go = _ctx.InstantiatePrefab(prefab);
go.transform.parent = transform;
go.SetActive(false);
lst.Add(go);
}
_pools.Add(t, lst);
}
public void Recycle(GameObject go) {
Assert.IsNotNull(go);
go.SetActive(false);
}
public GameObject Get(ObjectPoolType t, System.Action<GameObject> initFn = null) {
var pool = _pools[t];
if (pool == null) {
throw new System.Exception("Pool for type " + t + " does not exist, did you initialise it?");
}
for (int i = 0; i < pool.Count; i++) {
if (!pool[i].activeInHierarchy) {
pool[i].SetActive(true);
initFn?.Invoke(pool[i]);
return pool[i];
}
}
Debug.LogError("Object pool empty, cannot find new instance for " + t);
return null;
}
// Update is called once per frame
void Update() {
}
}
using System.Collections;
using System.Collections.Generic;
using TwoPM.View;
using UnityEngine;
using UnityEngine.Assertions;
using Zenject;
namespace GridBased.Fx
{
public class RecycleOnParticleComplete : MonoBehaviour
{
public ParticleSystem ParticleSystem;
private ObjectPoolingSystem _pool;
[Inject]
public void Inject(ObjectPoolingSystem pool) {
_pool = pool;
}
// Start is called before the first frame update
void Start() {
Assert.IsNotNull(ParticleSystem);
}
// Update is called once per frame
void Update() {
if (!ParticleSystem.IsAlive()) {
_pool.Recycle(gameObject);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment