- Home /
Trouble accessing child
I have this script on an object that is the parent of several objects that I want to access.
Hex = gameObject.transform.parent.gameObject;
startMarker = Hex.Find("Ball-Start/Cube");
This code only finds the first instance of Ball-Start/Cube in the scene, so multiple instances of the script end up controlling the same object.
How can I force this script to find only the Ball-Start/Cube that is attached to the group that it is a member of?
Wow, I really find it hard to believe that this is so difficult...
I can't simply navigate my hierarchy parent GameObject to child GameObject through some method?
I think I'm just going to try to re-structure the hierarchy so that all of these components are stored as components of the same object that has the controlling script.
Answer by Wolfram · Jun 03, 2011 at 10:19 PM
First of all you need to be aware that
anything you set to active==false can no longer be found via Find(), FindObjectsOfType(), or GetComponent...() (although the latter has an optional parameter that allows searching inactive components)
Find() in general is very expensive. So you should search your objects in Start() or Awake(), and store them in a variable. At the same time, this helps you to avoid the first problem, since once you have your target objects accessible via a variable, you can always access them, even when active==false.
Now, there are several methods to approach your problem. All of them start by storing the parent object containing the cubes in a variable (I don't speak UnityScript, so this is all C#, which is a better choice (=more powerful from a programmer's point of view) anyway, but all this is possible similarly in UnityScript):
public GameObject parentObject;
void Start(){
parentObject=GameObject.Find("Ball-Path");
}
(Instead of finding the object in Start(), you could also assign it in the Inspector manually.)
If the object named "Ball-Path" contains only cube objects you want to disable, your options are:
disable everything recursively starting from the parent: parentObject.SetActiveRecursively(false);
only switch off the renderers, so that the objects are no longer rendered, but remain active (note, here, too, you should instead store the objects in a Renderer[] array in Start, instead of calling the GetComponents... method every time):
foreach(Renderer r in parentObject.GetComponentsInChildren<Renderer>()) r.enabled=false;
If you only want to disable particular objects (e.g., named "Cube"), you can walk through the hierarchy with (note this loop will only find direct children of parentObject, you need to recurse yourself if you want to access the whole hierarchy this way):
foreach(Transform t in parentObject.transform) if(t.name=="Cube") t.gameObject.active=false;
EDIT: one more alternative:
In the worst case, if your objects can be anywhere in the scene hierarchy, but they are all called "Cube" (and no other obejcts are called "Cube"), you can still do this (however, very expensive in complex scenes):
private Renderer[] allRenderers; void Start(){ allRenderers=Object.FindObjectsOfType(typeof(Renderer)) as Renderer[]; } void DisableCubes(){ foreach(Renderer r in allRenderers) if(r.gameObject.name=="Cube"){ // found one! set object to inactive, or disable the renderer, as described above } }
I used a combination of looping through the child transforms in Start and setting vars and using SetActiveRecursively on those vars.
Answer by almo · Jun 03, 2011 at 07:31 PM
If it's a component, and there is only one in the group, you can use:
http://unity3d.com/support/documentation/ScriptReference/Component.GetComponentInChildren.html
If there might be many in the group,
http://unity3d.com/support/documentation/ScriptReference/Component.GetComponentsInChildren.html
will return a list of them.
No, it's not a Component, Ball-Path is an empty GameObject, with the GameObject Cube grouped under it.
Cube has a mesh and a light Component. I want to toggle active on the Cube GameObject.
Answer by DaveA · Jun 03, 2011 at 09:03 PM
Some ideas:
GameObject.Find(transform.name+"/Ball-Start/Cube");
Or use Tags
Or use specific names for the Cube
That won't work, since the parents are instantiated multiple times. Even referring to the whole path by name all the way up to the top might not be unique.