- Home /
Get a GameObject from a component
I want to get a list of GameObjects that contain this script named Alpha
I then destroy that script on all those Game Objects, but want to keep the list with the Game Objects.
I do it now by Having a list of
Alpha[] aList = GetComponentsInChildren<Alpha>();
// Destroy scripts here.
foreach(Alpha a in aList)
Destroy(a);
If I didn't destroy the scripts I know I could do
a.gameObject
However I do have to Destroy these scripts then I want to keep pointing to the GameObject. I tried things like this but failed to compile.
GameObject[] list;
list = GetComponentsInChildren<Alpha>() as GameObject;
I would rather not have to search through the components twice nor would I like to copy the array before destroying.
Answer by Chronos-L · Mar 15, 2013 at 10:29 AM
I came up with this:
List<GameObject> list = new List<GameObject>();
foreach( Alpha a in GetComponentsInChildren<Alpha>() ) {
list.Add( a.gameObject );
Destroy(a);
}
Basically, I see no major difference between array
and List
; anything you can do with an array
, you can do it with a List
. If you insist on using an array
, then convert the List
to array
by adding this line:
GameObject [] objectList = list.ToArray();
That is some (n^(numberOfChildren)) * n problem you have created there. Bad idea!
I don't see any problem with that. Where's the (n^numberOfChildren)*n)
complexity? How do you even get the (n^numberOfChildren)*n)
?
If you are talking about the foreach()
, I insists that you to read on how foreach()
works.
$$anonymous$$y script
void Start () {
List<GameObject> list = new List<GameObject>();
int i = 0;
foreach( Collider c in GetComponentsInChildren<Collider>() ) {
Debug.Log( (i++).ToString() );
list.Add(c.gameObject);
Destroy(c);
}
i = 0;
foreach( GameObject g in list ) {
g.name = (i++).ToString();
}
}
I am very sure that I have a O(n)
operation here in deleting the component (in my script, a collider). Had I have a O((n^x)*n)
, my child gameObject will not be named from { 0, ...., n-1 }; when I ran the code, my child gameObject no longer have a collider, and they are named from { 0, ..., n-1 }. So, I am certain that my code is O(n)
, not O((n^x)*n)
.
I suggest you read on how GetComponentsInChildren works.
You are looping n^2 best case, since you are iterating with the foreach as well as getting the components in the children every time the loop comes around.
I also suggest you learn to read better before clai$$anonymous$$g I posted the same question twice on my other post.
I made a mistake on your second question, and I apologize for not reading the question carefully and making false accuse.
From my understanding, in a foreach
loop, a enumerator is created from the Collections
used in the foreach
loop at the start of the loop. Then, the enumerator is used to iterate through the whole Collections
.
In this case, the foreach()
is getting its enumerator from a anonymous Component[]
return by the GetComponentsInChildren<>()
when the loop starts. So, GetComponentsInChildren<>()
is called only once at the start of the foreach()
loop.
To backup my point, I wrote the following script
using UnityEngine;
using System.Collections;
public class CheckArray : $$anonymous$$onoBehaviour {
private int count = 0;
// Use this for initialization
void Start () {
foreach( int val in GenerateArray() ) {
Debug.Log(val);
}
}
int[] GenerateArray() {
Debug.Log("Generate : " + (count++).ToString() );
return new int[]{ 2, 4, 6, 8, 10, 12 };
}
}
And this is my result:
If it is a O(n*n) as what you have implied on what is happening in the loop, then I will get 'Generate: 0' up to 'Generate: 5' for calling GenerateArray()
in every iteration of the foreach
.