- Home /
Counting active objects in a list
Utilizing the idea of object pooling, and storing said objects in a list. As seen in here: Object Pooling
I would like to run a check on that list to see if there are any objects active. I know you can utilize GameObject.activeInHierarchy on singular objects such as this Spawn() code:
List<GameObject> objectQueue;
void Spawn () {
for (int i = 0; i < objectQueue.Count; i++) {
if(!objectQueue[i].activeInHierarchy)
{
DetermineSpawnLocation(objectQueue[i]); //Decide where to spawn
objectQueue[i].SetActive(true); //object spawning
break;
}
}
}
I would like to do this check in a separate function as this Spawn code is called after some checks are made, and one of the checks I need to add is 'if there are any active shapes, wait for the count to be 0' (no active shapes in scene) before continuing. I was considering a foreach or for loop and manually counting active objects, but it seems there should be a better way.
If this question has be answered before please link it and reprimand me properly. Apologies if the answer is crazy simple.
TL;DR: How to count number of active objects within a list in simplest way possible.
Answer by george_vasilchenko · Jan 06, 2015 at 10:22 PM
Hello, here is a script that creates objects, puts them in a list, on left mouse click deactivates random amount of them and on the right mouse click counts remaining active instances. Hope that's what you needed. EDIT: if you click a scroll button, it prints out names of your active objects... Why do u need to use activeInHierarchy???
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SpawnObjectsCountActive : MonoBehaviour
{
int numActiveObj = 0;
int objToSpawn = 10;
public GameObject yourObject;
[SerializeField]
List<GameObject> yourObjects = new List<GameObject>();
List<string> namesOfActive = new List<string>();
void Start()
{
for (int i = 0; i < objToSpawn; i++)
{
GameObject aClone = Instantiate(yourObject, new Vector3(0, 0.5f + i, 0), Quaternion.identity) as GameObject;
aClone.transform.parent = transform;
aClone.name = "aClone_" + i;
yourObjects.Add(aClone);
}
}
void Update()
{
if (Input.GetMouseButtonDown(0)) RandomDeactivate(Random.Range(1, 9));
if (Input.GetMouseButtonDown(1)) Debug.Log(CountActive());
if (Input.GetMouseButtonDown(2)) PrintNamesOfActive();
}
private int CountActive()
{
for (int i = 0; i < yourObjects.Count; i++)
{
if (yourObjects[i].activeSelf == true)
{
numActiveObj++;
namesOfActive.Add(yourObjects[i].name);
}
}
return numActiveObj;
}
private void PrintNamesOfActive()
{
int count = 1;
foreach (string name in namesOfActive)
{
Debug.Log(string.Format("obj#{0}:{1} is active", count, name));
count++;
}
}
private void RandomDeactivate(int amount)
{
for (int i = 0; i < amount; i++)
{
yourObjects[i].SetActive(false);
}
}
}
This looks awesome. Similar to the route i was thinking of taking.
Barring that there is no simple yourObjects.activeInHiearchy.Count() method, this solution looks stellar.
EDIT: No need to use activeInHiearchy, was just a rough idea of how I imagined things could work if the function was built into unity. Sorry I should have been more clear :P
EDIT: I Have solved my issue, not really using anything from this thread, but hey, the question didn't exist before so maybe this will help someone in the future!
Answer by hexagonius · Jan 06, 2015 at 10:05 PM
Sorry for not answering your particular question, but why not have two lists, one holding active, one holding inactive objects. Move them over whenever a change occurs. Then you only need to check the count.
Btw. If all are identical objects, queue is actually a nice alternative to list, check it out.
The objects are identical, but their children can change. Would this break the use of a queue?
Thanks for the answer! I will add it to my notes for sure
Adding and removing objects from a list isn't very efficient, especially if they are in the middle.
Iterating through the list and counting active members would be much faster.
Depends on what you do with them. As soon as you need to pick a particular object you'll need a list. But if it's just a bunch of the same objects you just need one of, queue or stack are better ideas. The difference between those two is, with the queue you get the first object put in, with a stack the last (FIFO an LIFO, first or last in first out).
Its a question of accessibility. But list is fine :)
Right, but the use case at the top says "object pooling"
Generally when you're doing object pooling you have objects going active and inactive at different times, you're losing a lot of efficiency by adding them to separate lists every time they go active and inactive. It's better to just put them all in a big list and when you need a new one, iterate through the list until you find an inactive one and return it.
Answer by DanSuperGP · Jan 07, 2015 at 12:33 AM
Just loop through the list and count actives. It's simple, it's efficient. The whole point of lists is fast consecutive access.
You could do other things like use a linq query to get only the active objects from the collect, but that's going to be slower.
There's nothing wrong with the simple obvious way of doing this.
Your answer
Follow this Question
Related Questions
Count >= then object tag becomes active 1 Answer
A node in a childnode? 1 Answer
counting of two different objects 0 Answers
Get Count of a List inside a List / Class 1 Answer
ObjectPicker Source Code? 0 Answers