how to look for non-active gameobject in storage pool.

I have a a bunch of gameobjects stored in a pool and I want my code to check for the next gameobject that’s not active and activate it. Currently I’ve done it in 2 different ways. Method 1 is the most basic. I tell the code to check if object1 is active, if it isn’t then activate it, and if it is then check if object 2 is active. I just repeat the same line of code with object2, then object 3, etc. This is fine and easy to understand even for a beginner but it’s really only practical if you have very few objects. If your pool consists of something like 10+ objects then it’s a whole lot of extra unnecessary work. The way I handle these situations is with method 2. In method 2 I have an int variable named number. I store the objects in a list and then I randomize the number variable.

while(objectList[number].activeInHierarchy)
		{
			number = Random.Range(0,30);
		}

So it activates a random object, which is fine because they are all the same object anyway. Then when the time comes for the next activation, it’ll randomly choose a number again. If it’s already active it’ll just choose a new random number until it finds one that isn’t. The objects eventually deactivate so this allows the game to continuously activate gameobjects until the game stops regardless of how long it lasts. I GUESS WHAT I WANT TO KNOW IS: IS METHOD 2 A GOOD METHOD TO USE, OR IS IT VERY INEFFICIENT. IS THERE A BETTER WAY TO DO THIS?

Don’t know where to start, first i don’t speak perfect english sorry for that heh.

What you need is a function to loop from all your objects and when it finds one inactive store it on a variable.

You already have an array or list, now you have to make a for loop or for each loop (if you don’t know what im talking make a quick search its not a difficult concept, im not a pro neither)

for example:

//THIS GOES THROUGH YOU WHOLE ARRAY ONE BY ONE
for(var i = 0;i < objectList.Length; i++) {
 var objectToReturn : GameObject;
 if(!objectList*.activeInHerarchy){*

// THE “!” MEANS THAT “IF NOT” IN THIS CASE IF ITS NOT ACTIVE IN HERARCHY

objectToReturn = objectList*;*
return objectToReturn;
}
}
if you put this on a function and sotre it inside a variable you’ll have the object inside that variable :
var poolObject : GameObject;

poolObject = GiveMeOnePoolObject();

function GiveMeOnePoolObject(){

//THIS GOES THROUGH YOU WHOLE ARRAY ONE BY ONE
for(var i = 0;i < objectList.Length; i++) {
var objectToReturn : GameObject;
if(!objectList*.activeInHerarchy){*
// THE “!” MEANS THAT “IF NOT” IN THIS CASE IF ITS NOT ACTIVE IN HERARCHY

objectToReturn = objectList*;*
return objectToReturn;
}
}

}
I have made my own script for multiple pools of objects i just have to fill the quantity and object i want to instantiate inside the pool and then use some functions to play with them
i’ll leave it here if you want to use it or study it.
#pragma strict
import System.Collections.Generic;

//CREAR PILETAS DINAMICAS =START=
public class ObjectsPool extends System.Object {
* var Objeto : GameObject;*
* var Cantidad : int;*
* var Escalable : boolean;*
* var Pileta = new List.();*
}

var GrupoDePiletas : ObjectsPool[];

function Start () {
* for(var piletas : ObjectsPool in GrupoDePiletas){*
* for(var i = 0;i < piletas.Cantidad;i++){*
* var obj = Instantiate(piletas.Objeto,Vector3(0,0,0),Quaternion.identity);*
* obj.SetActive(false);*
* piletas.Pileta.Add(obj);*
* }*
* }*
}
//CREAR PILETAS DINAMICAS =END=

function LoadObject(PoolNumber : int) {
* for(var i = 0;i < GrupoDePiletas[PoolNumber].Pileta.Count;i++){*
_ if(!GrupoDePiletas[PoolNumber].Pileta*.activeInHierarchy){
return GrupoDePiletas[PoolNumber].Pileta;
}else if(GrupoDePiletas[PoolNumber].Pileta.activeInHierarchy && i == GrupoDePiletas[PoolNumber].Pileta.Count-1 && GrupoDePiletas[PoolNumber].Escalable){
var obj = Instantiate(GrupoDePiletas[PoolNumber].Objeto,Vector3(0,0,0),Quaternion.identity);
obj.SetActive(false);
GrupoDePiletas[PoolNumber].Pileta.Add(obj);
return obj;
}
}
return null;
}*_

function CheckActives(PoolNumber : int) {
* var activeObjects : int;*
* for(var i = 0;i < GrupoDePiletas[PoolNumber].Pileta.Count;i++){*
_ if(GrupoDePiletas[PoolNumber].Pileta*.activeInHierarchy){
activeObjects++;
}
}
return activeObjects;
}*_

function DisablePool(PoolNumber : int) {
* for(var i = 0;i < GrupoDePiletas[PoolNumber].Pileta.Count;i++){*
_ if(GrupoDePiletas[PoolNumber].Pileta*.activeInHierarchy){
GrupoDePiletas[PoolNumber].Pileta.SetActive(false);
}
}
}*_

As pointed out the random method gets less and less efficient as the pool gets more active. And will fail completely if every object is active.

Removing from a List works, but then you have to take care of adding them back into the list. I have an implementation of this here. Be sure to remove the last element from the list as indicated in the comments.

To improve the efficiency of the searching method you can simply store the position of the last object you used. Then start your search from there. This works on the principle that the most recently activated items in your collection are the most likely to still be active. Psudo code.

int positionInCollection;
GameObject[] pool;

GameObject GetThing(){
    int i = 0;
    while (i < pool.Length){
        while(positionInCollection < pool.Length){
            if (!pool[positionInCollection].activeInHierarchy){
                return pool[positionInCollection];
                positionInCollection ++;
                i++;
            }
        positionInCollection = 0;
        }
    }
    // The search has failed, grow the pool or return null as appropriate
    return null;
}

Some ugly loops in that code. Could probably be cleaned up a bit.