分享一个GameObject拓展类 查找子物体的并奉上效率测试

11 篇文章 0 订阅

先上测试结果 没效率的东西在方便还是不好用

这是测试代码

 bool ISO = true;
    float times = 0;
    void Start ()
    {
        Get_Component();
        System.Threading.Thread th = new System.Threading.Thread(thr);
        th.Start();
        TestSpeed();
    }
  
    void thr()
    {
        while (ISO)
            times += 0.001f;
    }
	void TestSpeed()
    {

        for(int i = 0; i < 100; i++)
        {
           // 分别测试这三种查找方式所用时间
           // Text te1 = gameObject.FindDeepChild<Text>("Scroll View/Viewport/parent/Members");
           // Text te2 = gameObject.FindDeepChild<Text>("Members");
            Text te3 = transform.Find("Scroll View").Find("Viewport").Find("parent").Find("Members").GetComponent<Text>();
        }
        ISO = false;
        print("完毕"+times);
    }

起一个线程用以计时

然后查找一百遍 然后查找四层以下的子物体

第三种Find("xxx")  用时

第二种直接输入子物体名称查找组件  用时

第三种输入清楚各个层的父物体名称用时

发现\

如果直接输入子物体名称去查找 写起来很方便 但是非常消耗时间 

用传统方式查找,时间很快 但是写起来有点麻烦,

输入层次关系查找 时间最快 写起来适中  

实践出真知

下边是拓展类的代码  里边还有其他几个拓展方法 就不一一赘述了.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// UI扩展工具类,被类中所有方法均是对GameObject或者Transform的修饰
/// </summary>
public static class UIUtility
{
    /// <summary>
    /// 查找本游戏物体下的特定名称的子物体系统,并将其返回
    /// </summary>
    /// <param name="_target">要在其中进行查找的父物体</param>
    /// <param name="_childName">待查找的子物体名称,可以是"/"分割的多级名称</param>
    /// <returns></returns>
    public static Transform FindDeepChild(this GameObject _target, string _childName)
    {
        Transform resultTrs = null;
        resultTrs = _target.transform.Find(_childName);
        if (resultTrs == null)
        {
            foreach (Transform trs in _target.transform)
            {
                resultTrs = trs.gameObject.FindDeepChild(_childName);
                if (resultTrs != null)
                    return resultTrs;
            }
        }
        return resultTrs;
    }

    /// <summary>
    /// 查找本游戏物体下的特定名称的子物体系统的特定组件,并将其返回
    /// </summary>
    /// <param name="_target">要在其中进行查找的父物体</param>
    /// <param name="_childName">待查找的子物体名称,可以是"/"分割的多级名称</param>
    /// <returns>返回找到的符合条件的第一个自物体下的指定组件</returns>
    public static T FindDeepChild<T>(this GameObject _target, string _childName) where T : Component
    {
        Transform resultTrs = _target.FindDeepChild(_childName);
        if (resultTrs != null)
            return resultTrs.gameObject.GetComponent<T>();
        return (T)((object)null);
    }
    /// <summary>
    /// 新建childObjectName命名的游戏物体并将其指定的子系统加入到本系统中
    /// </summary>
    /// <param name="target">要加入到的目标系统</param>
    /// <param name="childObjectName">待加入的子物体名称</param>
    public static Transform AddChild(this Transform target, string childObjectName)
    {
        GameObject go = new GameObject(childObjectName);
        target.AddChild(go.transform);
        return go.transform;
    }
    /// <summary>
    /// 将child指定的子系统加入到本系统中
    /// </summary>
    /// <param name="target">要加入到的目标系统</param>
    /// <param name="child">待加入的系统</param>
    public static void AddChild(this Transform target, Transform child)
    {
        child.SetParent(target);
        child.localScale = Vector3.one;
        child.localPosition = Vector3.zero;
        child.localEulerAngles = Vector3.zero;

        ChangeChildLayer(child, target.gameObject.layer);
    }
    /// <summary>
    /// 递归将本系统中的所有子系统的层级都指定为特定层级
    /// </summary>
    /// </summary>
    /// <param name="t">要修改的目标系统</param>
    /// <param name="layer">要指定的层级</param>
    private static void ChangeChildLayer(Transform t, int layer)
    {
        t.gameObject.layer = layer;
        foreach (Transform child in t)
        {
            child.gameObject.layer = layer;
            ChangeChildLayer(child, layer);
        }
    }
  
}

如果有哪里不对的 敬请指出,天天学习 好好向上 共同进步

在Unity中,如果你想要通过C#获取GameObject上某个Prefab型的物体,特别是Label型的,你可以先创建一个公共的委托或者属性来表示获取Label的行为,然后在C#脚本中查找并返回。假设你的Prefab有一个固定的标签名字比如"LabelComponent",可以这样做: ```csharp using UnityEngine; public class PrefabFinder : MonoBehaviour { // 创建一个公共委托,用于在找到Label时回调 public delegate void FoundLabel(GameObject labelGameObject); [HideInInspector] // 隐藏这个字段以便外部不会直接访问 public GameObject parentObject; // 保存需要查找的父物体 private void Start() { // 检查是否已经找到了Label,如果没有就搜索 if (FindLabel()) { // 如果找到了,调用委托通知外部 OnFoundLabel(labelGameObject); } } // 使用递归搜索Label组件 private bool FindLabel() { foreach (Transform child in parentObject.transform) { if (child.CompareTag("Label") && child.GetComponentInChildren<TextMeshProUGUI>() != null) // 确保是TextMeshProUGUI型的Label { foundLabel = child.gameObject; return true; } else if (child.GetComponentsInChildren<Prefab>().Length > 0) // 继续检查是否有Prefab { if (FindLabel()) // 如果Prefab有Label,则返回true return true; } } return false; } // 当找到Label时触发的事件 public event FoundLabel OnFoundLabel; // 公开这个方法供外部调用,当Label找到时,会自动触发事件 public void TryGetLabel() { if (foundLabel != null) { OnFoundLabel?.Invoke(foundLabel); // 调用委托,传递Label游戏对象 } } // 变量存储找到的Label游戏对象(这里仅作示例,实际应用中可能不需要) private GameObject foundLabel; } ``` 在这个例中,`OnFoundLabel`是外部可以订阅的事件,`TryGetLabel`方法会被外部调用来尝试获取Label。如果Label存在并且找到了,它会通过事件传递给订阅者。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值