纳金网

标题: 如何获取子物体孙物体重孙物体子孙后代所有的某个组件 [打印本页]

作者: 烟雨    时间: 2019-11-28 15:31
标题: 如何获取子物体孙物体重孙物体子孙后代所有的某个组件

来自:夏之末

如何获取子物体孙物体重孙物体子孙后代所有的某个组件呢?我的第一直觉是用递归,毕竟这玩意是个树状的嘛!但是话说回来我的递归有返回值的话我可能遍历到某个分支的尽头就返回了,所以我想了个办法,递归的方法让他没有返回值,给这个方法一个重载让它来返回,这样就解决了这个问题。emmm如果你听不懂的话直接看代码会好一些。
  1.      /// <summary>
  2.         /// 遍历所有子孙后代的组件
  3.         /// </summary>
  4.         /// <typeparam name="T">你要返回的类型</typeparam>
  5.         /// <param name="parent">父物体</param>
  6.         /// <param name="list">你返回的列表</param>
  7.         /// <returns></returns>
  8.         public static List<T> FindChildAll<T>(Transform parent, List<T> list) where T : Object
  9.         {
  10.             if (parent.childCount > 0)
  11.             {
  12.                 for (int i = 0; i < parent.childCount; i++)
  13.                 {
  14.                     T t = parent.GetChild(i).GetComponent<T>();
  15.                     if (t != null)
  16.                     {
  17.                         list.Add(t);
  18.                     }
  19.                     FindChildAll(parent.GetChild(i), list, i);
  20.                 }
  21.             }
  22.             return list;
  23.         }
  24.         /// <summary>
  25.         /// 遍历所有子孙后代的组件
  26.         /// </summary>
  27.         /// <typeparam name="T">你要返回的类型</typeparam>
  28.         /// <param name="parent">父物体</param>
  29.         /// <param name="list">你返回的列表</param>
  30.         /// <param name="depth">深度(用来重载)</param>
  31.         public static void FindChildAll<T>(Transform parent, List<T> list, int depth) where T : Object
  32.         {
  33.             if (parent.childCount > 0)
  34.             {
  35.                 for (int i = 0; i < parent.childCount; i++)
  36.                 {
  37.                     list.Add(parent.GetChild(i).GetComponent<T>());
  38.                     FindChildAll(parent.GetChild(i), list, i);
  39.                 }
  40.             }
  41.         }
复制代码

作者: 745951224    时间: 2019-11-29 10:14
讲道理,仔细看下这段代码就会发现,这写的毫无意义,
先说第二个FindChildAll<T>重载函数,在37行代码中没有对FindChildAll<T>的结果进行判空处理,按照这种写法,得到的List<T>中是可能会存在Null的
再说写法更改,我们都知道,List<T>是引用类型,所以第一个FindChildAll<T>函数仅仅需要取消返回值即可,递归完成后的List直接就是结果。

修改如下:
     /// <summary>
        /// 遍历所有子孙后代的组件
        /// </summary>
        /// <typeparam name="T">你要返回的类型</typeparam>
        /// <param name="parent">父物体</param>
        /// <param name="list">你返回的列表</param>
        /// <returns></returns>
        public static void FindChildAll<T>(Transform parent, List<T> list) where T : Component
        {
            if (parent.childCount > 0)
            {
                for (int i = 0; i < parent.childCount; i++)
                {
                    T t = parent.GetChild(i).GetComponent<T>();
                    if (t != null)
                    {
                        list.Add(t);
                    }
                    FindChildAll(parent.GetChild(i), list);
                }
            }
        }

调用如下:
List<Transform> transformList = new List<Transform>();
FindChildAll<Transform>(transform,transformList);
执行到这里的时候,transformList里就是遍历出来的所有子组件。不过这种方法不会获取对象本身,仅仅搜索对象的所有子、孙等的组件
作者: 745951224    时间: 2019-11-29 10:15
再补充个我个人使用的,用于获取对象以及对象层级之下的所有对象的指定组件
// <summary>
        /// 遍历所有子孙后代的组件
        /// </summary>
        /// <typeparam name="T">你要返回的类型</typeparam>
        /// <param name="parent">父物体</param>
        /// <param name="list">你返回的列表</param>
        /// <returns></returns>
        public static List<T> FindChildAll<T>(Transform parent, List<T> list) where T : Object
        {
            if (parent.childCount > 0)
            {
                for (int i = 0; i < parent.childCount; i++)
                {
                    T t = parent.GetChild(i).GetComponent<T>();
                    if (t != null)
                    {
                        list.Add(t);
                    }
                    FindChildAll(parent.GetChild(i), list, i);
                }
            }
            return list;
        }
作者: 745951224    时间: 2019-11-29 10:16
上条发错了,管理别通过
作者: 745951224    时间: 2019-11-29 10:20
一般我使用的:
        /// <summary>
        /// 遍历指定对象以及其下的指定组件
        /// </summary>
        /// <param name="parent">检索对象</param>
        /// <param name="list">容器列表</param>
        /// <returns></returns>
        public static void FindChildAll<T>(Transform obj, List<T> list) where T : Component
        {
            T t = obj.GetComponent<T>();
            if (t != null)
            {
                list.Add(t);
            }
            if (obj.childCount > 0)
            {
                for (int i = 0; i < obj.childCount; i++)
                {
                    FindChildAll(obj.GetChild(i), list);
                }
            }
        }




欢迎光临 纳金网 (http://rs.narkii.com/club/) Powered by Discuz! X2.5