-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathObjectPooler.cs
More file actions
152 lines (128 loc) · 4.4 KB
/
ObjectPooler.cs
File metadata and controls
152 lines (128 loc) · 4.4 KB
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using UnityEngine;
using System.Collections.Generic;
public class ObjectPooler : MonoBehaviour
{
public static ObjectPooler Instance { get; private set; }
[System.Serializable]
public class Pool
{
public string tag;
public GameObject prefab;
public int size;
public bool expandable = true;
}
[SerializeField] private List<Pool> pools;
private Dictionary<string, Queue<GameObject>> poolDictionary;
private Dictionary<string, GameObject> prefabDictionary;
private Dictionary<string, bool> expandableDictionary;
private Dictionary<GameObject, string> objectToTagDictionary;
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
return;
}
poolDictionary = new Dictionary<string, Queue<GameObject>>();
prefabDictionary = new Dictionary<string, GameObject>();
expandableDictionary = new Dictionary<string, bool>();
objectToTagDictionary = new Dictionary<GameObject, string>();
InitializePools();
}
private void InitializePools()
{
foreach (Pool pool in pools)
{
Queue<GameObject> objectPool = new Queue<GameObject>();
// Create a parent object for organization
GameObject poolParent = new GameObject(pool.tag + "_Pool");
poolParent.transform.SetParent(transform);
for (int i = 0; i < pool.size; i++)
{
GameObject obj = Instantiate(pool.prefab, poolParent.transform);
obj.SetActive(false);
objectPool.Enqueue(obj);
objectToTagDictionary.Add(obj, pool.tag);
}
poolDictionary.Add(pool.tag, objectPool);
prefabDictionary.Add(pool.tag, pool.prefab);
expandableDictionary.Add(pool.tag, pool.expandable);
}
}
public GameObject SpawnFromPool(string tag, Vector3 position, Quaternion rotation)
{
if (!poolDictionary.ContainsKey(tag))
{
Debug.LogWarning("Pool with tag " + tag + " doesn't exist!");
return null;
}
Queue<GameObject> objectPool = poolDictionary[tag];
// If the pool is empty and not expandable, return null
if (objectPool.Count == 0 && !expandableDictionary[tag])
{
Debug.LogWarning("No more objects in pool " + tag + " and it's not expandable!");
return null;
}
// If the pool is empty but expandable, create a new object
if (objectPool.Count == 0)
{
GameObject newObj = Instantiate(prefabDictionary[tag], transform.Find(tag + "_Pool"));
objectToTagDictionary.Add(newObj, tag);
newObj.SetActive(false);
objectPool.Enqueue(newObj);
}
GameObject objectToSpawn = objectPool.Dequeue();
objectToSpawn.SetActive(true);
objectToSpawn.transform.position = position;
objectToSpawn.transform.rotation = rotation;
// Call OnObjectSpawn method if the object has IPooledObject interface
IPooledObject pooledObj = objectToSpawn.GetComponent<IPooledObject>();
if (pooledObj != null)
{
pooledObj.OnObjectSpawn();
}
return objectToSpawn;
}
public void ReturnToPool(GameObject obj)
{
if (!objectToTagDictionary.ContainsKey(obj))
{
Debug.LogWarning("This object wasn't created from a pool!");
return;
}
string tag = objectToTagDictionary[obj];
obj.SetActive(false);
poolDictionary[tag].Enqueue(obj);
}
public void ClearPool(string tag)
{
if (!poolDictionary.ContainsKey(tag))
{
Debug.LogWarning("Pool with tag " + tag + " doesn't exist!");
return;
}
Queue<GameObject> objectPool = poolDictionary[tag];
while (objectPool.Count > 0)
{
GameObject obj = objectPool.Dequeue();
Destroy(obj);
}
}
public void ClearAllPools()
{
foreach (var pool in poolDictionary)
{
ClearPool(pool.Key);
}
}
}
// Interface for objects that need special initialization when spawned from pool
public interface IPooledObject
{
void OnObjectSpawn();
}