-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathPool.cs
159 lines (120 loc) · 3.69 KB
/
Pool.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
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
153
154
155
156
157
158
159
using System.Collections.Generic;
using UnityEngine;
namespace ToolBox.Pools
{
public sealed class Pool
{
private Poolable _prefab = null;
private int _currentCount = 0;
private Queue<Poolable> _entities = null;
private static Dictionary<int, Pool> _pools = new Dictionary<int, Pool>();
public Pool(Poolable prefab, int count)
{
_prefab = prefab;
_currentCount = count;
_entities = new Queue<Poolable>(count);
_pools.Add(prefab.gameObject.GetHashCode(), this);
Populate(count);
}
public Pool(GameObject prefab, int count)
{
_prefab = prefab.GetComponent<Poolable>();
if (_prefab == null)
{
_prefab = Object.Instantiate(prefab).AddComponent<Poolable>();
_prefab.gameObject.SetActive(false);
}
_currentCount = count;
_entities = new Queue<Poolable>(count);
_pools.Add(prefab.GetHashCode(), this);
Populate(count);
}
public static Pool Get(GameObject prefab)
{
var hasPool = _pools.TryGetValue(prefab.GetHashCode(), out var pool);
if (!hasPool)
pool = new Pool(prefab, 0);
return pool;
}
public void Populate(int count)
{
if (count <= 0)
return;
for (int i = 0; i < count; i++)
{
Poolable entity = Object.Instantiate(_prefab);
entity.SetPool(this);
_entities.Enqueue(entity);
entity.gameObject.SetActive(false);
}
_currentCount += count;
}
public Poolable GetEntity()
{
Poolable entity = GetEntityFromPool();
entity.ReturnFromPool();
return entity;
}
public Poolable GetEntity(Transform parent, bool spawnInWorldSpace)
{
Poolable entity = GetEntityFromPool();
entity.transform.SetParent(parent, spawnInWorldSpace);
entity.ReturnFromPool();
return entity;
}
public Poolable GetEntity(Vector3 position, Quaternion rotation)
{
Poolable entity = GetEntityFromPool();
entity.transform.SetPositionAndRotation(position, rotation);
entity.ReturnFromPool();
return entity;
}
public Poolable GetEntity(Vector3 position, Quaternion rotation, Transform parent, bool spawnInWorldSpace)
{
Poolable entity = GetEntityFromPool();
Transform entityTransform = entity.transform;
entityTransform.SetParent(parent, spawnInWorldSpace);
entityTransform.SetPositionAndRotation(position, rotation);
entity.ReturnFromPool();
return entity;
}
public T GetEntity<T>() where T : Component =>
GetEntity().GetComponent<T>();
public T GetEntity<T>(Transform parent, bool spawnInWorldSpace) where T : Component =>
GetEntity(parent, spawnInWorldSpace).GetComponent<T>();
public T GetEntity<T>(Vector3 position, Quaternion rotation) where T : Component =>
GetEntity(position, rotation).GetComponent<T>();
public T GetEntity<T>(Vector3 position, Quaternion rotation, Transform parent, bool spawnInWorldSpace) where T : Component =>
GetEntity(position, rotation, parent, spawnInWorldSpace).GetComponent<T>();
public void ReturnEntity(Poolable entity)
{
if (entity.Pool != this)
return;
_entities.Enqueue(entity);
_currentCount++;
entity.transform.SetParent(null, false);
entity.gameObject.SetActive(false);
}
private Poolable GetEntityFromPool()
{
Poolable entity;
if (_currentCount == 0)
{
entity = Object.Instantiate(_prefab);
entity.SetPool(this);
entity.gameObject.SetActive(true);
return entity;
}
entity = _entities.Dequeue();
if (entity == null)
{
entity = Object.Instantiate(_prefab);
entity.SetPool(this);
_currentCount++;
}
entity.gameObject.SetActive(true);
_currentCount--;
return entity;
}
}
}