Skip to content

Instantly share code, notes, and snippets.

@gamemachine
Created March 11, 2018 01:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gamemachine/66663c5460e6aa5b99be138c4a3de341 to your computer and use it in GitHub Desktop.
Save gamemachine/66663c5460e6aa5b99be138c4a3de341 to your computer and use it in GitHub Desktop.
using System.Collections.Generic;
using UnityEngine;
namespace AiGame
{
public class GameObjectPool : MonoBehaviour
{
public static Vector3 DefaultPosition = new Vector3(0f, 10000f, 0f);
public static GameObjectPool Instance;
private List<PooledGameObject> ToRemove = new List<PooledGameObject>();
private Dictionary<int, Queue<PooledGameObject>> Pool = new Dictionary<int, Queue<PooledGameObject>>();
private HashSet<PooledGameObject> PendingRelease = new HashSet<PooledGameObject>();
private void Awake()
{
Instance = this;
InvokeRepeating("UpdatePending", 1f, 0.5f);
}
public void TryReleasePooledChild(GameObject go)
{
foreach(var pooled in go.GetComponentsInChildren<PooledGameObject>())
{
PendingRelease.Remove(pooled);
Release(pooled);
}
}
public PooledGameObject Get(int poolId)
{
if (Pool[poolId].Count > 0)
{
var pooled = Pool[poolId].Dequeue();
return pooled;
} else
{
return null;
}
}
public void ReleaseInSeconds(PooledGameObject pooled, float seconds)
{
pooled.ReleaseAt = Time.time + seconds;
PendingRelease.Add(pooled);
}
public void Release(PooledGameObject pooled)
{
pooled.Release();
Pool[pooled.PoolId].Enqueue(pooled);
}
public void Create(int poolId, GameObject prefab, PooledType type, int partitionCount, int partitionSize)
{
Pool[poolId] = new Queue<PooledGameObject>();
for(int j=0;j<partitionCount;j++)
{
GameObject partition = new GameObject();
DontDestroyOnLoad(partition);
partition.name = string.Format("Partition-{0}-{1}", poolId, j);
partition.transform.position = DefaultPosition;
for (int i = 0; i < partitionSize; i++)
{
GameObject go = Instantiate(prefab);
go.name = string.Format("{0}-{1}", prefab.name, i);
PooledGameObject pooled = go.AddComponent<PooledGameObject>();
pooled.Setup(poolId, type, partition.transform);
Pool[poolId].Enqueue(pooled);
}
}
}
private void UpdatePending()
{
if (PendingRelease.Count == 0)
{
return;
}
foreach(PooledGameObject p in PendingRelease)
{
if (Time.time >= p.ReleaseAt)
{
ToRemove.Add(p);
}
}
foreach(PooledGameObject p in ToRemove)
{
PendingRelease.Remove(p);
Release(p);
}
ToRemove.Clear();
}
}
}
using UnityEngine;
namespace AiGame
{
public class PooledGameObject : MonoBehaviour
{
public int PoolId;
public Transform PartitionParent;
public PooledType Type;
public ParticleSystem[] Particles;
public Renderer[] Renderers;
public float ReleaseAt;
public void Setup(int poolId, PooledType type, Transform partitionParent)
{
PoolId = poolId;
Type = type;
PartitionParent = partitionParent;
switch (Type)
{
case PooledType.Renderer:
Renderers = gameObject.GetComponentsInChildren<Renderer>();
break;
case PooledType.Particle:
Particles = gameObject.GetComponentsInChildren<ParticleSystem>();
break;
}
Release();
}
public void Release()
{
ReleaseAt = 0f;
if (transform.parent != PartitionParent)
{
transform.SetParent(PartitionParent);
}
transform.position = GameObjectPool.DefaultPosition;
switch (Type)
{
case PooledType.Particle:
foreach (ParticleSystem ps in Particles)
{
ps.Stop();
}
break;
case PooledType.Renderer:
foreach (Renderer r in Renderers)
{
r.enabled = false;
}
break;
}
}
public void Show()
{
switch (Type)
{
case PooledType.Particle:
foreach (ParticleSystem ps in Particles)
{
ps.time = 0f;
ps.Play();
}
break;
case PooledType.Renderer:
foreach (Renderer r in Renderers)
{
r.enabled = true;
}
break;
}
}
private void OnDestroy()
{
//Debug.LogFormat("PooledGameObject destroyed");
}
}
}
namespace AiGame
{
public enum PooledType
{
None,
Renderer,
Particle
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment