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?

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
             }
     }
    

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.

Some ideas:

GameObject.Find(transform.name+“/Ball-Start/Cube”);

Or use Tags

Or use specific names for the Cube