- Home /
Finding the first gameobject in a List that meets a condition
I have an empty gameobject with several children; all the immediate children get assigned into a generic list at runtime for easy access later on. Please see below:
import System.Collections.Generic;
var allProjectiles = new List.<GameObject>();
var maxListSize : float = 40;
function Start () {
//Add every immediate child of the transform to the list above as a gameobject
for (var child : Transform in transform){
allProjectiles.Add(child.gameObject);
}
}
To begin with all of these children are deactivated(invisible). The idea is that only when I actually need a child, I will search for the first one in the list that has not yet been activated, then position and activate only that one. To emphasize, I'm not looking for every item in the list that meets the condition, only the first/highest one up the list. Of course though at some point all the gameobjects in the list will be activated eventually, so I think I would need an 'else' statement which will grab the first activated gameobject if a deactivated one cannot be found in the list. Any suggestions how to tackle this?
Answer by Hamesh81 · May 10, 2013 at 04:08 PM
Ok, I'm slowly working my way through a more straight forward approach (for me at least) for anyone else who has a similar problem to this. I've posted my update function below, it is 100% complete. I decided that instead of activating/deactivating gameobjects I will just turn of the renderer components as needed. Basically I'm using two generic lists; one for holding all of my projectiles, and a second for holding those which are available or in this case have their renderer turned off. When a check is triggered (for testing purposes this is just a key input right now) the list with all the projectiles is checked for any items with their renderer turned off and then those are added to the available projectiles list. The available projectiles list is then also checked for any items no longer available (have renderer turned on) and those are added to a third list and removed from the second.
I've finished the sorting now and fixed the sorting to work with multiple items via a third list. I also added a "Clear" to empty out the third list and then assigned the first item in the second list to a public variable so it is ready to be used by other scripts. Hope this helps someone!
function Update () {
if (Input.GetKeyDown ("space")) {
//For every avProjectile gameobject in the allProjectiles list
//If any of them have their renderer turned off
//Make sure they aren't in the list already
//And add them to the list availableProjectiles
//Assign the first availableProjectile
for (var avProjectile : GameObject in allProjectiles){
if (avProjectile.renderer.enabled == false) {
if (!availableProjectiles.Contains(avProjectile)) {
availableProjectiles.Add(avProjectile.gameObject);
}
}
}
//For every unProjectile gameobject in the availableProjectiles list
//If any of them have their renderer turned on
//Add them to the removableProjectiles list (ready for removal)
for (var unProjectile : GameObject in availableProjectiles){
if (unProjectile.renderer.enabled == true) {
if (!removableProjectiles.Contains(unProjectile)) {
removableProjectiles.Add(unProjectile.gameObject);
}
}
}
//For every unProjectileRemove gameobject in the removableProjectiles list
//Remove them from the availableProjectiles list
for (var unProjectileRemove : GameObject in removableProjectiles){
currentProjectile = null;
availableProjectiles.Remove (unProjectileRemove.gameObject);
}
//If the removableProjectiles list is not empty
//Clear the removableProjectiles list, Sort all availableProjectiles by name
if (removableProjectiles != null) {
SortAvProjectiles();
}
//Assign the first availableProjectile
if (availableProjectiles.Count > 0) {
currentProjectile = availableProjectiles[0];
}
}
}
//Clear the removableProjectiles list, Sort all availableProjectiles by name
function SortAvProjectiles () {
removableProjectiles.Clear();
availableProjectiles = availableProjectiles.OrderBy(function(go) go.name).ToList();
}
Answer by Jessy · May 07, 2013 at 03:15 PM
http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx
http://stackoverflow.com/questions/14032709/performance-of-find-vs-firstordefault
null will be returned if no item meets the condition.
var whatever = allProjectiles.Find(p => !p.Activated) ?? allProjectiles.First();
Interesting and surprising that Find has better performance then FirstOrDefault, though I feel
var notActivated = allProjections.FirstOrDefault(p=>!p.Activated)
reads a lot better
Thanks a lot, this seems a lot more complicated than I originally thought. I was considering using a for loop to find all the deactivated children first and then sorting them by their name/index to get the "first" one after that. $$anonymous$$ore lines of code involved but the syntax would be easier for me to understand and adapt I think. Anyway, I tried using Jessy's code but I am getting 2 token errors for both "p" and "?". Is there something else I need to add?
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
How to find out if an int already exists in an int list 0 Answers
Best way to check for supports in building system? 1 Answer
how to check if object already exists in a list 1 Answer
List.Where does not return 1 Answer