[SOLVED]Disable multiple game objects - Object Pooling

Hello , I’m trying to disable some game objects that are spawned with the object pooling. The game objects that I want to disable are enemies, they must be disable when is active another game object that I have chosen.

I tried this but it does not work:

 using UnityEngine;
using System.Collections;
public class ifBossActive : MonoBehaviour {
     public GameObject boss;
     private GameObject[] enemies;
     void Start () {
         enemies = GameObject.FindGameObjectsWithTag ("Enemy");
     }
        
     void Update () {
        
         if (boss.activeInHierarchy) {
             for(int i = 0; i < enemies.Length; i++)
             {
                 enemies [i].SetActive (false);
             }
         }
     }
}

This is the code for the object pooling (used for enemies):

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class enemiesGen : MonoBehaviour {
     public float spawnTime = 0.1f;
     public GameObject enemy;
     public int pooledAmount = 8;
     List<GameObject> enemies;
   
  void Start () {
         enemies = new List<GameObject> ();
         for (int i = 0; i < pooledAmount; i++)
         {
             GameObject obj = (GameObject)Instantiate(enemy);
             obj.SetActive (false);
             enemies.Add(obj);
         }
         InvokeRepeating ("spawnEnemy", spawnTime, spawnTime);
     }
   
  void spawnEnemy () {
         for (int i = 0; i < enemies.Count; i++) {
             if (!enemies [i].activeInHierarchy)
             {
transform.position = new Vector3 (transform.position.x, transform.position.y, transform.position.z + Random.Range(50f, 250f)); 

                 enemies [i].transform.position = transform.position;
                 enemies [i].transform.rotation = transform.rotation;
                 enemies [i].SetActive (true);

                 break;
             }
         }
     }
}

How can I fix? Thanks in advance.

First of all, C# prefers classes with pascal case (aka the first letter is uppercase too)
The boss is child of something, that can get deactivated?
Did you do debugs?

1 Like

I am not sure where your problem is, the SetActive(false) works fine.

I did a test to see if this all worked out fine. (and it did)

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class test : MonoBehaviour {
    public int maxSpawn = 8;
    public float spawnTime = 0.1f;
    public GameObject enemyToSpawn;
    private List<GameObject> enemies;
    private float nextSpawn = 0;

    void Start() {
        // make sure that if you are not using a prefab, that we disable the current enemy
        if (enemyToSpawn.activeInHierarchy)
            enemyToSpawn.SetActive(false);

        // keep a list of enemies
        enemies = new List<GameObject>();

        // this works perfectly
        //for (var i = 0; i < maxSpawn; i++) {
        //    var enemySpawned = Instantiate(enemyToSpawn);
        //    enemies.Add(enemySpawned);
        //    enemySpawned.SetActive(false);
        //}
        
    }


    void Update() {
        // check all the enemies to see if they are still alive.
        // if not, disable them
        foreach (var enemy in enemies)
        {
            if (enemy.activeInHierarchy)
            {
                var health = enemy.GetComponent<Health>();
                if (health != null)
                {
                    if (health.health <= 0) enemy.SetActive(false);
                }
            }
        }
        // instead of invoke repeating, lets use timed events
        if (nextSpawn > Time.time) return;
        SpawnEnemy();
    }

    void SpawnEnemy() {
        // keep count and make sure we dont go over our limit
        var count = 0;
        // this will keep the enemy we spawn
        GameObject enemySpawned = null;
        // go through each current enemy and see if it is active
        foreach (var enemy in enemies) {
            if (enemy.activeInHierarchy)
                count++;
            else // if it is not active, keep the first one we find
                if(enemySpawned == null) enemySpawned = enemy;
        }

        // if we can spawn
        if (count < maxSpawn) {
            // if we didnt find an enemy in the list, make one and add it to the list.
            if (enemySpawned == null)
            {
                enemySpawned = Instantiate(enemyToSpawn);
                enemies.Add(enemySpawned);
            }

            // set the position, rotation and make it active.
            enemySpawned.transform.position = transform.position;
            enemySpawned.transform.rotation = transform.rotation;
            enemySpawned.SetActive(true);

            // advance the time, but only if we spawned an enemy
            nextSpawn = Time.time + spawnTime;
        }
    }
}


public class Health : MonoBehaviour {
    public int health = 100;
    public int maxHealth = 100;

    // methods used for broadcasting damage/healing
    public void Damage(int amount) {
        health -= amount;
        if(health > maxHealth) health = maxHealth;
        if(health < 0) health = 0;
    }

    public void Heal(int amount){
        health += amount;
        if(health > maxHealth) health = maxHealth;
        if(health < 0) health = 0;
    }
}
1 Like

OK, I see your problem.

Every 0.1 seconds, you activate all of your enemies, which means all 8 or so enemies activate at the same time. There is no “pooling”

So, every frame, if the boss is there, all of the enemies deactivate, up to 0.1 seconds later, the all activate, and then the next frame they all deactivate again.

1 Like

Thanks for the answers!

I tried to change the object pooling directly, in this way:

public GameObject boss;

void SpawnEnemy() {

for (int i = 0; i < enemies.Count; i++) {
if (!enemies [i].activeInHierarchy && !boss.activeInHierarchy)
{
transform.position = new Vector3 (transform.position.x, transform.position.y, transform.position.z + Random.Range(50f, 250f));
enemies [i].transform.position = transform.position;
enemies [i].transform.rotation = transform.rotation;
enemies [i].SetActive (true);
break;
}

if (boss.activeInHierarchy)
{
spawnTime = 0f;
enemies [i].SetActive (false);
CancelInvoke ();
break;
}
}
}

But I still can not disable.
PS: the boss is a prefab located in Prefabs/ folder and it is spawned after 50 seconds of the game.

you should separate your concerns here.

1, you want to disable the enemies when the boss is active, that needs to happen every frame, so it should be put into an update.

2, in SpawnEnemy, if the boss is active, you need to just exit the method.

1 Like

Thank you, now everything works perfectly. :slight_smile:

Hi,
I know this post is very old, but I’m looking for a solution like this. how did you solve it Thank you very much