-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPoolManager.cs
111 lines (96 loc) · 3.05 KB
/
PoolManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
using UnityEngine;
using System.Collections.Generic;
public static class PoolManager
{
const int DefaultPoolSize = 3;
class Pool
{
int nextId = 1;
int preferredPoolSize;
Stack<GameObject> inactive;
GameObject prefabToPool;
public int Count
{
get { return inactive.Count; }
}
public Pool(GameObject prefab) : this(prefab, DefaultPoolSize)
{
}
public Pool(GameObject prefab, int poolSize)
{
prefabToPool = prefab;
inactive = new Stack<GameObject>(poolSize);
preferredPoolSize = poolSize;
}
public GameObject Spawn(Vector3 position, Quaternion rotation)
{
GameObject gameObject;
if (inactive.Count == 0)
{
gameObject = GameObject.Instantiate(prefabToPool, position, rotation);
gameObject.name = prefabToPool.name + " (" + (nextId++) + ")";
gameObject.AddComponent<PoolMember>().pool = this;
}
else
{
gameObject = inactive.Pop();
if (gameObject == null)
{
//INFO: the item in our stack is null
Debug.Log("Tried to spawn but returned null");
return Spawn(position, rotation);
}
}
gameObject.transform.position = position;
gameObject.transform.rotation = rotation;
gameObject.SetActive(true);
return gameObject;
}
public void Despawn(GameObject gameObject)
{
if (Count >= preferredPoolSize)
{
GameObject.Destroy(gameObject);
return;
}
gameObject.transform.parent = null;
gameObject.SetActive(false);
inactive.Push(gameObject);
}
}
class PoolMember : MonoBehaviour
{
public Pool pool;
}
static Dictionary<GameObject, Pool> pools = new Dictionary<GameObject, Pool>();
public static void Init(GameObject prefab, int poolSize = DefaultPoolSize)
{
if (!pools.ContainsKey(prefab))
{
pools[prefab] = new Pool(prefab, poolSize);
}
}
public static GameObject Spawn(GameObject prefab, Vector3 position, Quaternion rotation)
{
//INFO: init a pool for this type of prefab if there isn't already one
Init(prefab);
return pools[prefab].Spawn(position, rotation);
}
public static void Despawn(List<GameObject> gameObjects)
{
gameObjects.ForEach(x => Despawn(x));
}
public static void Despawn(GameObject gameObject)
{
var poolMember = gameObject.GetComponent<PoolMember>();
if (!poolMember)
{
Debug.Log("Object '" + gameObject.name + "' wasn't spawned from a pool. Destroying it instead.");
GameObject.Destroy(gameObject);
}
else
{
poolMember.pool.Despawn(gameObject);
}
}
}