改为了Dictionary2.0的代码如下,你会吗?

改为了Dictionary2.0的代码如下,你会吗?

这个方法纯粹是为了偷懒而写的。 当功能比较简单的时候,一个一个的拖动对象就太麻烦了。 如果子对象可以通过名称直接绑定到脚本上,确实会节省很多时间。

原理是先在父体下的第一个子对象中查找是否有需要的子对象。 如果没有,则继续递归查找。 如果有的话返回。

修改部分:每次搜索子对象时,都要遍历变换下的所有子对象,太消耗性能。 如果一个变换的子对象数量达到一定数量,就会变得很卡。

因此,第一次遍历transform的所有子对象时,使用List来保存。 将此转换集合保存在字典中像素游戏素材,键为转换,值为列表。 以后只需要检查字典中是否有transform的key就可以了。 如果有,则直接从字典中通过浅拷贝的方式添加。 如果没有keyunity 找到所有子物体,则会遍历所有子对象并添加到字典中。 然后它遍历并搜索它。 当它找到相应的子对象时橙光游戏,它会中断并返回该子对象。

这是代码:

    private Dictionary> transformListDic = new Dictionary>();
    public Transform GetChildTransform(string childName, Transform t, bool isFindAll)
    {
        Transform child = t.Find(childName);
        if(child == null && !isFindAll)
        {
            Debug.Log("!isFindAll");
            return null;
        }
        if (t.childCount < 1)
        {
            Debug.Log("t.childCount = " + t.childCount);
            return null;
        }
        else
        {
            List childList = new List();
            if (transformListDic.ContainsKey(t))//检查是否有key,如果有就直接从字典里浅拷贝添加。
            {
                childList.AddRange(transformListDic[t]); 
            }
            else//如果没有就添加transform下所有子物体进集合,并用transform为key来保存
            {
                for (int i = 0; i < t.childCount; ++i)
                {
                    GetChildList(t.GetChild(i), childList);
                }
                transformListDic.Add(t, childList);
            }
            for (int i = 0; i < childList.Count; ++i)
            {
                if (childList[i].name == childName)
                {
                    child = childList[i];
                    break;
                }
            }
            return child;
        }
    }
    public T GetChildComponent(string childName, Transform t, bool isFindAll) where T : Component
    {
        Transform child = GetChildTransform(childName, t, true);
        GameObject childObj = child.gameObject;
        return (T)childObj.GetComponent();
    }
    private List GetChildList(Transform t, List childList)
    {
        List transforms = new List();
        foreach(Transform childT in t)
        {
            transforms.Add(childT);
            if(childT.childCount != 0)
            {
                GetChildList(childT, transforms);
            }
        }
        childList.AddRange(transforms);
        return childList;
    }

开玩笑地说,这是1.0版本。 这是一个刚刚实施的方法,将来可以扩展。

=============2.0==============

使用了一段时间后,突然发现自己用List很傻。 每次去寻找子对象,都得遍历它。 实在无法忍受,所以我把List改成了Dictionary。 2.0的代码如下:

    private Dictionary> transformMainDic = new Dictionary>();
    public Transform GetChildTransform(string childName, Transform t, bool isFindAll)
    {
        float time = Time.time;
        Transform child = t.Find(childName);
        if (child == null && !isFindAll)
        {
            Debug.Log("!isFindAll");
            return null;
        }
        if (t.childCount < 1)
        {
            Debug.Log("t.childCount = " + t.childCount);
            return null;
        }
        else
        {
            Dictionary childDic = new Dictionary();
            if (!transformMainDic.ContainsKey(t))
            {
                for (int i = 0; i < t.childCount; ++i)
                {
                    GetChildDic(t.GetChild(i), childDic);
                }
                transformMainDic.Add(t, childDic);
            }
            child = transformMainDic[t][childName];
            Debug.LogFormat("耗时{0}秒", Time.time - time);
            return child;
        }
    }
    public T GetChildControl(string childName, Transform t) where T : Component
    {
        Transform child = GetChildTransform(childName, t, true);
        GameObject childObj = child.gameObject;
        return (T)childObj.GetComponent();
    }
    private Dictionary GetChildDic(Transform t, Dictionary childDic)
    {
        Dictionary transforms = new Dictionary();
        foreach(Transform childT in t)
        {
            if(childDic.containsKey(childT.name))
            {
                Debug.LogWarningFormat("已经存在名为{0}的组件", childT.name);
                continue;
            }
            transforms.Add(childT.name, childT);
            if(childT.childCount != 0)
            {
                GetChildDic(childT, transforms);
            }
        }
        foreach(var myEntry in transforms)
        {
            childDic.Add(myEntry.Key, myEntry.Value);
        }
        return childDic;
    }

如果只需要组件本身,不需要组件上的脚本函数,那么 GetChildTransform 方法就足够了。

如果您需要子对象组件上的脚本,请调用 GetChildComponent 方法。例如

    private Image NullImg;
    void Start ()
    {
        NullImg = GetChildControll("NullImg", this.transform, true);
        Debug.Log(NullImg);
    }

打印出来如下图

同时unity 找到所有子物体,你还可以使用NullImg.sprite等Image组件下的方法、属性和字段,这意味着你可以完全获取Image本身。

毕竟是1.0版本,是为了简化一些步骤而想出来的方法。 有不足之处请指出。 共同进步~

文章来源:https://blog.csdn.net/DoyoFish/article/details/80689767