Created
March 11, 2018 01:33
-
-
Save gamemachine/66663c5460e6aa5b99be138c4a3de341 to your computer and use it in GitHub Desktop.
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.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