I have prefabs with a component say, "ClassA". These prefabs have multiple children with the component "ClassB". ClassB is used to store configuration properties that define the ClassA prefab. So the idea is that I can search through all of my Class A prefabs and check the properties on its children so I can determine which prefab I need. The reason I have used children to store these properties is because I wanted to use editor gizmos to make it easier to config each prefab (there are 27 children per prefab which would make it confusing to name & edit as standard public properties on the prefab).
The problem I'm having is that `myPrefab.GetComponentsInChildren()` is returning null, which really spoils my day. I don't want to have to instantiate all of my prefabs just to pick which one I need. Why is it that I can access properties on the prefab (ClassA) but not its children? Is there a way to achieve this without simply having all of my properties in ClassA?
Thanks in advance.
edit for clarity:
myPrefab - ClassA <-- I can access the component on the prefab just fine
child - ClassB ← but I can’t access the components in the prefab’s children at all
GetComponentsInChildren has that already mentiond restriction to return only active gameobjects / components. Just iterate manually through them. Something like that:
private static void ProcessChild<T>(Transform aObj, ref List<T> aList) where T : Component
{
T c = aObj.GetComponent<T>();
if (c != null)
aList.Add(c);
foreach(Transform child in aObj)
ProcessChild<T>(child,ref aList);
}
public static T[] GetAllChilds<T>(Transform aObj) where T : Component
{
List<T> result = new List<T>();
ProcessChild<T>(aObj, ref result);
return result.ToArray();
}
You can of course implement it as extension methods to easily access them:
public static T[] GetAllChilds<T>(this Transform aObj) where T : Component
{
List<T> result = new List<T>();
ProcessChild<T>(aObj, ref result);
return result.ToArray();
}
public static T[] GetAllChilds<T>(this GameObject aObj) where T : Component
{
List<T> result = new List<T>();
ProcessChild<T>(aObj.transform, ref result);
return result.ToArray();
}
PrefabA contains a script ClassA, and PrefabB contains a script ClassB, then you add PrefabB's to PrefabA (and make sure A stays a prefab), is that basically what you did? If so, the problem may be that you can't 'nest' prefabs and have them retain their lower-level individuality.
Other than that, maybe you can post some code and/or screenshot for us to review.
I had the same Problem.
Searching components from childObjects in a prefab via editorWindow returns null.
My solution was using GetComponentsInChildren(true) to include nonActive childObjects.
The reason is because, as noted in the documentation, GetComponentsInChildren only returns components on active objects. Un-instantiated prefabs (i.e., assets in your asset database) are all deactivated (and must be—you get an error message saying that Unity will crash if you try to create an asset using an active GameObject). As such, it seems you must instantiate your prefab in a new scene to extract any needed data from children, or to make any necessary modifications to the source asset.
I’m having this issue too. My solution is to simply descend the hierarchy depth-first and call GetComponent on each child, looking for what I need. I guess GetComponent and GetComponentsInChildren behave differently unfortunately.