与其自己做递归,为什么不简单地使用GameObject.GetComponentsInChildren
返回 GameObject 或其任何子对象中 Type 类型的所有组件。
Unity 在子游戏对象上递归搜索组件。这意味着它还包括目标 GameObject 的所有子 GameObject,以及所有后续子 GameObject。
并做例如
using System.Linq;
接着
public static List<GameObject> FindAllGameObjectsInGameObject(GameObject gameObjectToTraverse)
{
// This already gives you ALL transform components anywhere nested
// under the given object including inactive and disabled ones
// INCLUDING the given object itself
var allChildTransforms = gameObjectToTraverse.GetComponentsInChildren<Transform>(true);
// This uses Linq to rather get all the according GameObjects
// See https://docs.microsoft.com/dotnet/api/system.linq.enumerable.select
var allChildGameObjects = allChildTransforms.Select(t => t.gameObject);
// Optional if you don't want to return the original given object itself
// See https://docs.microsoft.com/dotnet/api/system.linq.enumerable.where
var onlyChildGameObjects = allChildGameObjects.Where(c => c!= gameObjectToTraverse);
return onlyChildGameObjects.ToList();
}
忘记递归,因为 Unity 已经为你做了它;)
那么实际上泛型参数是做什么T用的呢?您可能想在第一次通话中使用它
var allChildComponents = gameObjectToTraverse.GetComponentsInChildren<T>(true);
为了宁愿只获得具有T附加类型组件的对象。
只是为了实际回答您的尝试:您可以使用可选参数,例如
public static List<GameObject> FindAllGameObjectsInGameObject(GameObject gameObjectToTraverse, List<GameObject> list = new List<GameObject>())
{
foreach (Transform child in gameObjectToTraverse.transform)
{
list.Add(child.gameObject);
FindAllGameObjectsInGameObject(child.gameObject, list);
}
}
所以当你第一次调用它时,你就这样做
var objs = FindAllGameObjectsInGameObject(objectToTraverse);
在这种情况下,会自动创建一个新列表作为第二个参数。然后它在递归调用中在内部传递。
或者你可以稍微混淆一下,然后简单地将这两者分开:
public static List<GameObject> FindAllGameObjectsInGameObject(GameObject gameObjectToTraverse)
{
return FindAllGameObjectsInGameObjectInternal(objectToTraverse, new List<GameObject>());
}
private static List<GameObject> FindAllGameObjectsInGameObjectInternal(GameObject gameObjectToTraverse, List<GameObject> list)
{
foreach (Transform child in gameObjectToTraverse.transform)
{
list.Add(child.gameObject);
FindAllGameObjectsInGameObjectInternal(child.gameObject, list);
}
}
但是,使用可选参数解决方案,您可以让开发人员有机会重用已经存在的列表,而不是每次都创建一个新列表;)