查看: 1942|回复: 4
打印 上一主题 下一主题

[其他] 如何获取子物体孙物体重孙物体子孙后代所有的某个组件

[复制链接]

9903

主题

126

听众

7万

积分

首席设计师

Rank: 8Rank: 8

纳金币
53488
精华
316

最佳新人 热心会员 灌水之王 活跃会员 突出贡献 荣誉管理 论坛元老

跳转到指定楼层
楼主
发表于 2019-11-28 15:31:14 |只看该作者 |倒序浏览

来自:夏之末

如何获取子物体孙物体重孙物体子孙后代所有的某个组件呢?我的第一直觉是用递归,毕竟这玩意是个树状的嘛!但是话说回来我的递归有返回值的话我可能遍历到某个分支的尽头就返回了,所以我想了个办法,递归的方法让他没有返回值,给这个方法一个重载让它来返回,这样就解决了这个问题。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.         }
复制代码
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏1 支持支持0 反对反对0
回复

使用道具 举报

5

主题

7

听众

2429

积分

中级设计师

Rank: 5Rank: 5

纳金币
149
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

沙发
发表于 2019-11-29 10:14:59 |只看该作者
讲道理,仔细看下这段代码就会发现,这写的毫无意义,
先说第二个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里就是遍历出来的所有子组件。不过这种方法不会获取对象本身,仅仅搜索对象的所有子、孙等的组件
回复

使用道具 举报

5

主题

7

听众

2429

积分

中级设计师

Rank: 5Rank: 5

纳金币
149
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2019-11-29 10:15:59 |只看该作者
再补充个我个人使用的,用于获取对象以及对象层级之下的所有对象的指定组件
// <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;
        }
回复

使用道具 举报

5

主题

7

听众

2429

积分

中级设计师

Rank: 5Rank: 5

纳金币
149
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

地板
发表于 2019-11-29 10:16:26 |只看该作者
上条发错了,管理别通过
回复

使用道具 举报

5

主题

7

听众

2429

积分

中级设计师

Rank: 5Rank: 5

纳金币
149
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

5#
发表于 2019-11-29 10:20:17 |只看该作者
一般我使用的:
        /// <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);
                }
            }
        }
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-13 20:48 , Processed in 0.091857 second(s), 27 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部