- Home /
Object Pooling issue. GameObject instantiating 1 bullet instead of multiple bullets
So I have this GO which supposed to shoot multiple bullets everytime it changes its designated spot/position. Unfortunately, it only instantiates one bullet everytime it changes position. I'm using object pooling to instantiate the bullet. I think the issues here are my loops and coroutine but can't still figure it out.
Here's my messy code. PLEASE TAKE NOTE: I didn't include all the variables here but I declared everything in my actual code, so don't worry about it.
public GameObject bullet; void Start ()
{
// OBJECT POOLING RIGHT HERE!!!
// To store pooledAmount of game objects once the game starts
pooledAmount = 50;
bulletS = new List<GameObject> ();
for (int i = 0; i < pooledAmount; i++) {
GameObject obj = (GameObject)Instantiate (bullet);
obj.SetActive (false);
bulletS.Add (obj);
}
StartCoroutine ("Pattern");
}
IEnumerator Pattern ()
{
// First Pattern Spot
while (transform.position != patternSpot [0].position) {
transform.position = Vector2.MoveTowards (transform.position, posXY, movementSpeed * Time.deltaTime);
yield return null;
}
StartCoroutine ("Shoot", 1f);
yield return new WaitForSeconds (3f);
// Second Pattern Spot
while (transform.position != patternSpot [1].position) {
transform.position = Vector2.MoveTowards (transform.position, posXY1, movementSpeed * Time.deltaTime);
yield return null;
}
StartCoroutine ("Shoot", 1f);
yield return null;
}
IEnumerator Shoot () {
//Don't pool any game objects that is already active
for (int i = 0; i < bulletS.Count; i++) {
if (bulletS[i] != null) {
if (!bulletS [i].activeInHierarchy) {
bulletS [i].transform.position = transform.position;
bulletS [i].transform.rotation = transform.rotation;
bulletS [i].SetActive (true);
break;
}
} yield return new WaitForSeconds (.1f);
}
}
Answer by ScaniX · Jul 22, 2016 at 11:50 PM
Is the Shoot()
method supposed to activate more than one bullet? If so, you should remove the break in line 45 that exits the loop after the first bullet creation.
I don't know how many bullets you want to create each time. You maybe want a second counter to break if for example 5 bullets have been created.
IEnumerator Shoot () {
//Don't pool any game objects that is already active
int createdBullets = 0;
for (int i = 0; i < bulletS.Count; i++) {
if (bulletS[i] != null) {
if (!bulletS [i].activeInHierarchy) {
bulletS [i].transform.position = transform.position;
bulletS [i].transform.rotation = transform.rotation;
bulletS [i].SetActive (true);
if (++createdBullets == 5) break;
}
}
yield return new WaitForSeconds (.1f);
}
}
(I guess there is another part somewhere that disables the bullets again?)
So I have a little issue again. It seems like when I add another two or more spots to change its position, it doesn't instantiate multiple bullets accurately. The first two spots are a good. It instantiates, lets say 20 bullets per spot. However, on the third spot, it doesn't instantiate any. Then on the 4th spot it will only instantiate less than 10 bullets. The coroutine should be instantiating 20 bullets whenever the game object change its position but it's not.
Here's my code for the coroutine:
IEnumerator Pattern ()
{
// First Pattern Spot
while (transform.position != patternSpot [0].position) {
transform.position = Vector2.$$anonymous$$oveTowards (transform.position, posXY, movementSpeed * Time.deltaTime);
yield return null;
}
StartCoroutine ("Shoot");
yield return new WaitForSeconds (3f);
// Second Pattern Spot
while (transform.position != patternSpot [1].position) {
transform.position = Vector2.$$anonymous$$oveTowards (transform.position, posXY1, movementSpeed * Time.deltaTime);
yield return null;
}
StartCoroutine ("Shoot");
yield return new WaitForSeconds (5f);
// Third Pattern Spot
while (transform.position != patternSpot [2].position) {
transform.position = Vector2.$$anonymous$$oveTowards (transform.position, posXY2, movementSpeed * Time.deltaTime);
yield return null;
}
StartCoroutine ("Shoot");
yield return new WaitForSeconds (5f);
// Fourth Pattern Spot
while (transform.position != patternSpot [3].position) {
transform.position = Vector2.$$anonymous$$oveTowards (transform.position, posXY3, movementSpeed * Time.deltaTime);
yield return null;
}
StartCoroutine ("Shoot");
yield return new WaitForSeconds (5f);
// Back to First Pattern Spot
while (transform.position != patternSpot [0].position) {
transform.position = Vector2.$$anonymous$$oveTowards (transform.position, posXY, movementSpeed * Time.deltaTime);
yield return null;
}
StartCoroutine ("Shoot");
yield return null;
}
I also have a simple code attached to the bullet below. I'm not sure if it affects the behavior of the bullets.
void OnEnable () {
Invoke ("Destroy", 3f);
}
void Destroy () {
gameObject.SetActive (false);
}
void OnDisable () {
CancelInvoke ();
}
Well the original pool you posted allows 50 bullets to be used at the same time.
I am not sure if OnEnable() is called when you activate the GameObject. You should probably explicitly call a method to start the deactivate timer on your bullet whenever you activate them.
Try using breakpoints or pause the game and check your scene hierarchy. You could also dump the bullets and their state in the Shoot() method to see if there are any available.