6.不记录默认和重复控件

6.重复无用判断


6.1 知识点

不用的控件,不记录。可以自己定规则决定什么控件是不用的。比如,控件名是默认名就认为不会专门使用它们。

声明控件默认名列表

private List<string> defaultName = new List<string>() { "Image",
                                                        "Text (TMP)",
                                                        "RawImage",
                                                        "Background",
                                                        "Checkmark",
                                                        "Label",
                                                        "Text (Legacy)",
                                                        "Arrow",
                                                        "Placeholder",
                                                        "Fill",
                                                        "Handle",
                                                        "Viewport"};

找控件时发现默认名就跳出当前循环

private ControlStrInfo FindControl<T>(GameObject obj) where T:UIBehaviour
{
    ControlStrInfo info = new ControlStrInfo();
    T[] controls = obj.GetComponentsInChildren<T>();
    Type type = typeof(T);
    for (int i = 0; i < controls.Length; i++)
    {
        // 通过判断该控件名字是否是不需要进行代码生成的 如果是 就直接跳过
        // 1. 不用的控件,不记录
        if (defaultName.Contains(controls[i].name) ||
            controls[i].name == obj.name)
            continue;
        //...
    }
}

重复名字的控件,不记录。可以自己定规则,比如要使用的控件不能够重名。声明记录控件的字典。

// 用于记录 对应控件类型的字典
private Dictionary<string, Type> controlType = new Dictionary<string, Type>();
if (controlType.ContainsKey(controls[i].name))
{
    // 2. 重复名字的相同控件判断
    if (controlType[controls[i].name] == type)
    {
        EditorUtility.DisplayDialog("重复控件名", $"有两个控件类型相同的对象重名了{controls[i].name}", "确定");
        return null;
    }
}

如果同一个对象上,有两种UI控件,记录更重要的。

if (controlType.ContainsKey(controls[i].name))
{
    // 2. 重复名字的相同控件判断
    if (controlType[controls[i].name] == type)
    {
        EditorUtility.DisplayDialog("重复控件名", $"有两个控件类型相同的对象重名了{controls[i].name}", "确定");
        return null;
    }
    // 3. 同名对象,不同类型的控件 比如 Button和Image会出现在一个对象上
    // 只需要保证重要的控件已经生成代码了就可以了 相对不重要的控件 直接忽略不记录
    else
        continue;
}

6.2 知识点代码

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class UIPanelTool : EditorWindow
{
    private List<string> defaultName = new List<string>() { "Image",
                                                            "Text (TMP)",
                                                            "RawImage",
                                                            "Background",
                                                            "Checkmark",
                                                            "Label",
                                                            "Text (Legacy)",
                                                            "Arrow",
                                                            "Placeholder",
                                                            "Fill",
                                                            "Handle",
                                                            "Viewport"};

    //用于记录 对应控件类型的字典
    private Dictionary<string, Type> controlType = new Dictionary<string, Type>();

    [MenuItem("GameObject/UI/自动生成面板脚本文件")]
    private static void CreateToolPanel()
    {
        UIPanelTool win = EditorWindow.GetWindow<UIPanelTool>("自动生成面板脚本工具");
        win.Show();
        //对面板上显示的相关信息进行初始化
        //需要自动生成的代码 在这里 就应该拼接好
        win.InitInfo();
    }

    public void InitInfo()
    {
        //1.获取选择的对象
        GameObject obj = Selection.activeGameObject;
        if (obj == null)
            return;
        //获取所有的按钮控件
        ControlStrInfo btnInfo = FindControl<Button>(obj);

        btnInfo = FindControl<Image>(obj);

        Debug.Log(btnInfo.nameStr);
    }

    private ControlStrInfo FindControl<T>(GameObject obj) where T:UIBehaviour
    {
        ControlStrInfo info = new ControlStrInfo();
        T[] controls = obj.GetComponentsInChildren<T>();
        Type type = typeof(T);
        for (int i = 0; i < controls.Length; i++)
        {
            //通过判断该控件名字是否是不需要进行代码生成的 如果是 就直接跳过
            //1.不用的控件,不记录
            if( defaultName.Contains(controls[i].name) ||
                controls[i].name == obj.name)
                continue;

            if(controlType.ContainsKey(controls[i].name))
            {
                //2.重复名字的相同控件判断
                if (controlType[controls[i].name] == type)
                {
                    EditorUtility.DisplayDialog("重复控件名", $"有两个控件类型相同的对象重名了{controls[i].name}", "确定");
                    return null;
                }
                //3.同名对象,不同类型的控件 比如 Button和Image会出现在一个对象上
                //  只需要保证重要的控件已经生成代码了就可以了 相对不重要的控件 直接忽略不记录
                else
                    continue;
            }

            controlType.Add(controls[i].name, type);

            //声明相关的拼接
            info.nameStr += $"public {type.Name} {controls[i].gameObject.name};\n\t";
            info.findStr += $"{controls[i].gameObject.name} = this.transform.Find(\"{controls[i].gameObject.name}\").GetComponent<{type.Name}>();\n\t\t";

            switch (type.Name)
            {
                case "Button":
                    info.listenerStr += $"{controls[i].gameObject.name}.onClick.AddListener(On{controls[i].gameObject.name}Click);\n\t\t";
                    info.funcStr += $"protected virtual void On{controls[i].gameObject.name}Click(){{}}\n\t";
                    break;
                case "Toggle":
                    info.listenerStr += $"{controls[i].gameObject.name}.onValueChanged.AddListener(On{controls[i].gameObject.name}ValueChanged);\n\t\t";
                    info.funcStr += $"protected virtual void On{controls[i].gameObject.name}ValueChanged(bool value){{}}\n\t";
                    break;
                case "Slider":
                    info.listenerStr += $"{controls[i].gameObject.name}.onValueChanged.AddListener(On{controls[i].gameObject.name}ValueChanged);\n\t\t";
                    info.funcStr += $"protected virtual void On{controls[i].gameObject.name}ValueChanged(float value){{}}\n\t";
                    break;
                default:
                    break;
            }
        }

        return info;
    }

    private void OnGUI()
    {
        if (GUILayout.Button("选择保存路径"))
        {
            string path = EditorUtility.SaveFilePanel("脚本保存路径", Application.dataPath, "", ".cs");
            if( path != "" )
            {

            }
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏