Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Accessing Prefab Children in Editor Scripts

Discussion in 'Editor & General Support' started by mayekol, Sep 4, 2008.

  1. mayekol

    mayekol

    Joined:
    Oct 23, 2007
    Posts:
    115
    I seem to be having some difficulty in accessing children of a prefab (in the Project View) using a menu script. What I would really like to do is access the components of each of the children, however it seems that the GetComponentsInChildren does not work for prefabs (Assets) in the Project view.

    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using UnityEditor;
    5. using System;
    6.  
    7. public class CustomMenu
    8. {  
    9.  
    10.   [MenuItem("Custom/ListTransforms")]
    11.   static void ListChildTransforms()
    12.   {
    13.      GameObject go = Selection.activeGameObject;
    14.        
    15.      Component [] allTransforms =   go.GetComponentsInChildren(typeof(Transform));
    16.      Debug.Log(allTransforms.Length);
    17.        
    18.        
    19.      Transform objTransform = (Transform)go.GetComponent(typeof(Transform));   
    20.      Debug.Log(objTransform.position);
    21.   }
    22. }          
    23.  
    The first Debug.Log returns 0 as does any GetComponentsInChildren call.

    The second Debug.Log using GetComponent returns the correct value (-0.6, 0.2, 0.7) which is the root transform of the prefab (the prefab does have multiple child objects under the root), but I was still surprised that the GetComponentsInChildren did not also return the root transform.

    Any help would be appreciated,
    Thanks mayekol
     
  2. fooguru

    fooguru

    Joined:
    Aug 27, 2009
    Posts:
    10
    I'm having the same problem - I can't access child gameobjects or components in a uninitiated prefab (assets). GetComponentsInChildren returns 0 while GetComponents works but only for the root gameobject.
     
  3. hjbaard

    hjbaard

    Joined:
    Feb 5, 2010
    Posts:
    38
    I had the same problem but I fixed it.
    In stead of doing this:

    Code (csharp):
    1. foreach (Transform child in go.GetComponentsInChildren<Transform>())
    2.    child.gameObject.something = somethingElse;
    You can say:

    Code (csharp):
    1. foreach(Transform child in go.transform)
    2.    child.gameObject.something = somethingElse;
    This looks strange (to me) but it works :)
     
  4. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Awesome! Thanks a lot hjbaard, I was at a dead end before finding your post :)

    Now, if only Unity was capable of showing nested prefabs below the second level, it would be awesome. Sigh.
     
  5. Acegikmo

    Acegikmo

    Joined:
    Jun 23, 2011
    Posts:
    1,293
    Here's a little snippet that might be of use, as this still doesn't work in Unity 5.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3.  
    4. public static class GameObjectExtensions {
    5.  
    6.     public static T[] GetComponentsInChildrenOfAsset<T>( this GameObject go ) where T : Component {
    7.         List<Transform> tfs = new List<Transform>();
    8.         CollectChildren( tfs, go.transform );
    9.         List<T> all = new List<T>();
    10.         for (int i = 0; i < tfs.Count; i++)
    11.             all.AddRange( tfs[i].gameObject.GetComponents<T>() );
    12.         return all.ToArray();
    13.     }
    14.    
    15.     static void CollectChildren( List<Transform> transforms, Transform tf){
    16.         transforms.Add(tf);
    17.         foreach(Transform child in tf){
    18.             CollectChildren(transforms, child);
    19.         }
    20.     }
    21.  
    22. }
    23.  
    You can then call it like this:

    Code (CSharp):
    1. myObject.GetComponentsInChildrenOfAsset<Transform>();
     
    Eristen, TooManySugar and iwillbenice like this.
  6. iwillbenice

    iwillbenice

    Joined:
    Jun 7, 2013
    Posts:
    21
    Nice and easy. Works on Unity 5.0.2f1.
    I could not just use GetComponentInChildren<T> on it, but when I use new Unity this function works fine.
     
    Last edited: Feb 25, 2016