Пример #1
0
    //不支持嵌套
    public static void ChangeDepth(GameObject find_Prefab, GameObject template_Prafab)
    {
        //查找出一个克隆对象的所有子节点有的UITemplate
        XUITemplate[] template_templateComps = template_Prafab.GetComponentsInChildren <XUITemplate>(true);
        //目标模板的索引字典
        Dictionary <string, XUITemplate> template_Guid2TemplateDict = new Dictionary <string, XUITemplate>();
        //
        string template_headName = "";

        //遍历
        for (int i = 0; i < template_templateComps.Length; i++)
        {
            //获取组件
            XUITemplate tmp = template_templateComps[i];
            template_Guid2TemplateDict[tmp.GUID] = tmp;
            template_headName = tmp.headName;
        }

        XUITemplate[] find_allComps = find_Prefab.GetComponentsInChildren <XUITemplate>(true);

        //设置父子节点关系
        for (int i = 0; i < find_allComps.Length; ++i)
        {
            //获取组件
            XUITemplate find_tmp = find_allComps[i];

            if (find_tmp.headName == template_headName && find_tmp.index == "0")
            {
                XUITemplate[] find_tmps = find_tmp.GetComponentsInChildren <XUITemplate>(true);
                Dictionary <string, XUITemplate> find_Guid2TmpDict = new Dictionary <string, XUITemplate>();
                for (int j = 0; j < find_tmps.Length; ++j)
                {
                    find_Guid2TmpDict[find_tmps[j].GUID] = find_tmps[j];
                }

                for (int j = 0; j < find_tmps.Length; ++j)
                {
                    if (find_tmps[j].headName == template_headName && find_tmps[j].index != "0")
                    {
                        XUITemplate find_parent = find_tmps[j].transform.parent.GetComponent <XUITemplate>();

                        XUITemplate template_parent = template_Guid2TemplateDict[find_tmps[j].GUID].transform.parent.GetComponent <XUITemplate>();

                        //父子关系有变化,要重新设置
                        if (template_parent.GUID != find_parent.GUID)
                        {
                            find_tmps[j].transform.SetParent(find_Guid2TmpDict[template_parent.GUID].transform);
                        }
                    }
                }
                break;
            }
        }

        //设置深度
        for (int i = 0; i < find_allComps.Length; ++i)
        {
            //获取组件
            XUITemplate find_comp = find_allComps[i];

            if (find_comp.headName == template_headName && find_comp.index == "0")
            {
                int signIndex = find_comp.transform.GetSiblingIndex();//5

                XUITemplate[] find_tmps = find_comp.GetComponentsInChildren <XUITemplate>(true);

                //重新计算,深度
                for (int j = 0; j < find_tmps.Length; ++j)
                {
                    if (find_tmps[j].headName == template_headName && find_tmps[j].index != "0")
                    {
                        int index = template_Guid2TemplateDict[find_tmps[j].GUID].transform.GetSiblingIndex();//1

                        find_tmps[j].transform.SetSiblingIndex(index);
                    }
                }

                break;
            }
        }
    }
Пример #2
0
    /// <summary>
    /// 应用替换,传入前要实例化好
    /// 在Hierarchy
    /// </summary>
    /// <param name="find_Prefab">需要替换的根节点</param>
    /// <param name="template_Prafab">目标预设</param>
    private static GameObject ReplaceComponent(GameObject find_Prefab, GameObject template_Prafab)
    {
        GameObject result = find_Prefab;

        //查找出一个克隆对象的所有子节点有的UITemplate
        XUITemplate[] template_allComps = template_Prafab.GetComponentsInChildren <XUITemplate>(true);

        //目标模板的索引字典
        Dictionary <string, XUITemplate> template_GuidToCompDict = new Dictionary <string, XUITemplate>();

        string template_headName = "";

        //遍历
        for (int i = 0; i < template_allComps.Length; i++)
        {
            //获取组件
            XUITemplate template_comp = template_allComps[i];

            template_GuidToCompDict[template_comp.GUID] = template_comp;
            template_headName = template_comp.headName;
        }

        //
        XUITemplate[] find_allComps = find_Prefab.GetComponentsInChildren <XUITemplate>(true);

        //判断是否有相同模板嵌套
        for (int i = 0; i < find_allComps.Length; ++i)
        {
            XUITemplate find_comp = find_allComps[i];
            if (find_comp.headName == template_headName && find_comp.index == "0")
            {
                int           count             = 0;
                XUITemplate[] find_tmp_allComps = find_comp.GetComponentsInChildren <XUITemplate>(true);
                for (int j = 0; j < find_tmp_allComps.Length; ++j)
                {
                    if (find_tmp_allComps[j].headName == find_comp.headName && find_tmp_allComps[j].index == "0")
                    {
                        ++count;
                    }
                }

                //int count = 0;
                //XUITemplate[] find_tmp_allComps = find_Prefab.GetComponentsInChildren<XUITemplate>(true);
                //for (int j = 0; j < find_tmp_allComps.Length; ++j)
                //{
                //    if (find_tmp_allComps[j].headName == find_comp.headName && find_tmp_allComps[j].index == "0")
                //    {
                //        ++count;
                //    }
                //}

                if (count > 1)
                {
                    if (EditorUtility.DisplayDialog("提示", find_Prefab.name + "有模板嵌套\r\n(请处理再替换)\r\n(请处理再替换)\r\n(请处理再替换)", "确定"))
                    {
                        GameObject.DestroyImmediate(find_Prefab);
                        GameObject.DestroyImmediate(template_Prafab);
                        return(null);
                    }
                    else
                    {
                        GameObject.DestroyImmediate(find_Prefab);
                        GameObject.DestroyImmediate(template_Prafab);
                        return(null);
                    }
                }
            }
        }

        //当前模块使用了模板数量
        int useTemplateCount = 0;

        for (int i = 0; i < find_allComps.Length; ++i)
        {
            XUITemplate find_XUITemplate = find_allComps[i];
            if (find_XUITemplate.headName == template_headName && find_XUITemplate.index == "0")
            {
                ++useTemplateCount;
            }
        }

        //理论数量
        int theoryCount = useTemplateCount * template_GuidToCompDict.Count;

        //操作功能索引标志
        int operateSing = 0;

        List <GameObject> willDelObjList = new List <GameObject>();

        if (theoryCount > find_allComps.Length)
        {
            Debug.Log("模板有新节点增加");
            operateSing = 1;
        }
        else if (theoryCount < find_allComps.Length)
        {
            Debug.Log("模板有新节点删除");
            if (EditorUtility.DisplayDialog("提示", "新Prefab的节点有删除,确定要替换么?\r\n(请谨慎处理)\r\n(请谨慎处理)\r\n(请谨慎处理)", "确定", "取消") == false)
            {
                GameObject.DestroyImmediate(find_Prefab);
                GameObject.DestroyImmediate(template_Prafab);
                return(null);
            }
            operateSing = -1;
        }
        else
        {
            Debug.Log("模板节点数没变化");
            operateSing = 0;
        }

        //已经复制了的对象
        Dictionary <int, GameObject> yet_copyDict = new Dictionary <int, GameObject>();

        //待替换prefab的所有子节点
        Transform[] find_allChilds = find_Prefab.GetComponentsInChildren <Transform>(true);
        for (int i = 0; i < find_allChilds.Length; ++i)
        {
            GameObject find_childObj = find_allChilds[i].gameObject;

            if (find_childObj == null)
            {
                continue;
            }

            XUITemplate find_comp = find_childObj.GetComponent <XUITemplate>();

            if (find_comp != null && template_GuidToCompDict.ContainsKey(find_comp.GUID))
            {
                int find_childId = find_childObj.GetInstanceID();

                if (yet_copyDict.ContainsKey(find_childId))
                {
                    continue;
                }

                yet_copyDict[find_childId] = find_childObj;

                //新建一个新的对象,然后粘贴属性
                GameObject new_Instance = new GameObject();
                new_Instance.name = find_childObj.name;
                if (find_childObj.transform.parent != null)
                {
                    new_Instance.transform.SetParent(find_childObj.transform.parent);
                }
                else
                {
                    result = new_Instance;
                }
                new_Instance.transform.localPosition = find_childObj.transform.localPosition;
                new_Instance.transform.localRotation = find_childObj.transform.localRotation;
                new_Instance.transform.localScale    = find_childObj.transform.localScale;

                ////////////////////
                new_Instance.transform.SetSiblingIndex(find_childObj.transform.GetSiblingIndex());

                //复制子节点
                int count = find_childObj.transform.childCount;
                List <Transform> find_childList = new List <Transform>();
                for (int j = 0; j < count; ++j)
                {
                    Transform child = find_childObj.transform.GetChild(j);
                    find_childList.Add(child);
                }
                foreach (var v in find_childList)
                {
                    v.SetParent(new_Instance.transform);
                }

                //原先的对象组件数组
                Component[] find_copiedComponents = find_childObj.GetComponents <Component>();

                //复制对象所有组件,不包括子节点
                Component[] template_copiedComponents = template_GuidToCompDict[find_comp.GUID].GetComponents <Component>();

                //开始复制
                foreach (var template_copiedComponent in template_copiedComponents)
                {
                    string template_typeString = template_copiedComponent.GetType().ToString();
                    if (retainDict.ContainsKey(template_typeString))
                    {
                        //配置表填写要保留的属性
                        List <string> propertyList = retainDict[template_typeString];

                        //查找该Object的所有属性,是否满足条件需要保留
                        Type template_type = template_copiedComponent.GetType();
                        System.Reflection.PropertyInfo[] template_propertyInfos = template_type.GetProperties();
                        for (int k = 0; k < template_propertyInfos.Length; k++)
                        {
                            string template_name = template_propertyInfos[k].Name;

                            if (propertyList.Contains(template_name))
                            {
                                //从原先的组件找出要保留的属性,然后赋值给新创建的组件
                                foreach (var find_copiedComponent in find_copiedComponents)
                                {
                                    if (find_copiedComponent.GetType() == template_type)
                                    {
                                        Type find_type = find_copiedComponent.GetType();
                                        System.Reflection.PropertyInfo[] find_propertyInfos = find_type.GetProperties();

                                        for (int m = 0; m < find_propertyInfos.Length; ++m)
                                        {
                                            if (find_propertyInfos[m].Name == template_name)
                                            {
                                                object before_v = find_propertyInfos[m].GetValue(find_copiedComponent, null);

                                                template_propertyInfos[k].SetValue(template_copiedComponent, before_v, null);

                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    //复制组件
                    UnityEditorInternal.ComponentUtility.CopyComponent(template_copiedComponent);
                    UnityEditorInternal.ComponentUtility.PasteComponentAsNew(new_Instance);
                }

                //增加新节点////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                if (operateSing == 1)
                {
                    //已经添加的模板组件,存起来,方便找出是否目标prefab是否有新节点增加或者删除
                    Dictionary <string, XUITemplate> find_yetAddDict = new Dictionary <string, XUITemplate>();

                    foreach (var v in find_childList)
                    {
                        //加入已经有的组件
                        XUITemplate tmp = v.GetComponent <XUITemplate>();
                        if (tmp != null && tmp.headName == find_comp.headName)
                        {
                            find_yetAddDict[tmp.GUID] = tmp;
                        }
                    }

                    //如果模板节点有增加,则加入新增的模板节点
                    XUITemplate template_tmp = template_GuidToCompDict[find_comp.GUID];
                    for (int j = 0; j < template_tmp.transform.childCount; ++j)
                    {
                        Transform child = template_tmp.transform.GetChild(j);

                        XUITemplate tmp = child.GetComponent <XUITemplate>();

                        //如果没有,则为目标模板新添加的节点,则实例化加入到新节点
                        if (!find_yetAddDict.ContainsKey(tmp.GUID))
                        {
                            GameObject obj = GameObject.Instantiate(child.gameObject);
                            obj.name = child.name;
                            obj.transform.SetParent(new_Instance.transform);
                        }
                    }
                }

                //删除节点////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                if (operateSing == -1)
                {
                    //已经添加的模板组件,存起来,方便找出是否目标prefab是否有新节点增加或者删除
                    Dictionary <string, XUITemplate> find_yetAddDict = new Dictionary <string, XUITemplate>();
                    foreach (var v in find_childList)
                    {
                        //加入已经有的组件
                        XUITemplate tmp = v.GetComponent <XUITemplate>();
                        if (tmp != null && tmp.headName == find_comp.headName)
                        {
                            find_yetAddDict[tmp.GUID] = tmp;
                        }
                    }

                    //
                    Dictionary <string, XUITemplate> template_yetAddDict = new Dictionary <string, XUITemplate>();
                    int template_childCount = template_GuidToCompDict[find_comp.GUID].transform.childCount;
                    for (int j = 0; j < template_childCount; ++j)
                    {
                        Transform   child = template_GuidToCompDict[find_comp.GUID].transform.GetChild(j);
                        XUITemplate tmp   = child.GetComponent <XUITemplate>();
                        if (tmp != null && tmp.headName == find_comp.headName)
                        {
                            template_yetAddDict[tmp.GUID] = tmp;
                        }
                    }

                    foreach (var d in find_yetAddDict)
                    {
                        //如果没有,则为目标模板已经删除的节点,则删除
                        if (!template_yetAddDict.ContainsKey(d.Key))
                        {
                            willDelObjList.Add(d.Value.gameObject);
                        }
                    }
                }
            }
        }

        //删除旧的
        foreach (var d in yet_copyDict)
        {
            GameObject.DestroyImmediate(d.Value);
        }
        yet_copyDict.Clear();

        foreach (var v in willDelObjList)
        {
            GameObject.DestroyImmediate(v);
        }
        willDelObjList.Clear();

        return(result);
    }