Unity automatically generates prefab scripts

There are many UI interfaces in Unity development, including different components, such as Button, Image, etc. We need to find them according to the correct path and hold them. This step will be very cumbersome and easy when the interface is very large. wrong. The automatic code generation tool introduced in this article is to solve this dilemma. It can automatically obtain the components we want and generate them with one click. I hope it will be helpful to you.

Generate code display

Insert image description here

Design ideas

We want to make the object automatically generate code, which is nothing more than three steps. The first step is to find the object, the second step is to record all the components of the object that need to generate code, and the third step is to create a file and write the recorded content.

Operating procedures

  1. Make the prefabricated interface we need. To get the component object, start with T_
  2. Right-click the root node of the interface and click SpawnUICode (generate UI template) . An operation window will pop up.
  3. Click on the window to select the module to be generated by the script , and our preset module drop-down menu will pop up. Select our corresponding module to generate the script under the selected module.
    Insert image description here
    Insert image description here
    Insert image description here

Source code

popup window code


class GeneratePathSelectWindow : EditorWindow
{
    
    
    private string[] path = new string[]
    {
    
    
        "Common",
        "Store",
        "Role",
        "Host",
    };

    private static GameObject selectGo;

    public void ShowWindow(GameObject go)
    {
    
    
        selectGo = go;
        EditorWindow.GetWindow(typeof(GeneratePathSelectWindow));
    }

    void OnGUI()
    {
    
    
        if (GUILayout.Button("选择脚本要生成的模块"))
        {
    
    

            ShowGenericMenu();
        }
    }

    private void ShowGenericMenu()
    {
    
    
        GenericMenu menu = new GenericMenu(); //初始化GenericMenu
        for (int i = 0; i < path.Length; i++)
        {
    
    
            menu.AddItem(new GUIContent(path[i]), false, SelectPath, path[i]); //向菜单中添加菜单项
        }
        menu.ShowAsContext(); //显示菜单

    }

    void SelectPath(object floderName)
    {
    
    
        string t = floderName.ToString();
        Debug.Log("选择路径:" + floderName);
         UICodeSpawner.SpawnUICode(selectGo, t);//生成脚本代码
    }
}

Content writing code

  private static void SpawnPanelCode(GameObject gameObject)
    {
    
    
        Path2WidgetCachedDict?.Clear();
        Path2WidgetCachedDict = new Dictionary<string, List<Component>>();
        FindAllWidgets(gameObject.transform, "");
        SpawnCodeForPanel(gameObject);


        AssetDatabase.Refresh();
    }

    private static void SpawnCodeForPanel(GameObject gameObject)
    {
    
    
        var strPanelName = gameObject.name;
        var strFilePath = Application.dataPath + defaultUIPath + selectFolderName + "/UIBehaviour/" + strPanelName;
        if (!Directory.Exists(strFilePath))
        {
    
    
            Debug.LogError("请先(SpawnerUICode)生成UI代码模板");
            Directory.CreateDirectory(strFilePath);
            return;
        }

        SpawnCodeForPanelComponentBehaviour(gameObject);
    }

    private static void SpawnCodeForPanelComponentBehaviour(GameObject gameObject)
    {
    
    
        if (null == gameObject)
        {
    
    
            return;
        }

        string strDlgName = gameObject.name;
        string strDlgComponentName = gameObject.name + "View";
        string strFilePath = Application.dataPath + defaultUIPath + selectFolderName + "/UIBehaviour/" + strDlgName;
        if (!Directory.Exists(strFilePath))
        {
    
    
            Directory.CreateDirectory(strFilePath);
        }

        strFilePath = Application.dataPath + defaultUIPath + selectFolderName + "/UIBehaviour/" + strDlgName +
                      "/" + strDlgComponentName + ".cs";
        StreamWriter sw = new StreamWriter(strFilePath, false, Encoding.UTF8);
        StringBuilder strBuilder = new StringBuilder();
        strBuilder.AppendLine("using UnityEngine;");
        strBuilder.AppendLine("using UnityEngine.UI;");
        strBuilder.AppendLine();
        strBuilder.AppendLine("namespace AutoBuildCode");
        strBuilder.AppendLine("{");
        strBuilder.AppendLine("\t/// <summary>");
        strBuilder.AppendLine("\t/// 此文件为脚本自动生成并且覆盖;");
        strBuilder.AppendLine("\t/// 非必要请不要在此作修改");
        strBuilder.AppendLine("\t/// </summary>");

        strBuilder.AppendFormat("\tpublic class {0} : MonoBehaviour \r\n", strDlgComponentName)
            .AppendLine("\t{");
        strBuilder.AppendFormat("\t\tprivate Transform uiTransform = null;\r\n");
        CreateDeclareCode(ref strBuilder);
        strBuilder.AppendLine();
        CreateWidgetBindCode(ref strBuilder, gameObject.transform);
         CreateDestroyWidgetCode(ref strBuilder);
        strBuilder.AppendLine("\t}");
        strBuilder.AppendLine("}");

        sw.Write(strBuilder);
        sw.Flush();
        sw.Close();
    }

    private static void CreateDestroyWidgetCode(ref StringBuilder strBuilder)
    {
    
    
        strBuilder.AppendFormat("\t\tpublic void DestroyWidget()");
        strBuilder.AppendLine("\n\t\t{");
        CreateDlgWidgetDisposeCode(ref strBuilder);
        strBuilder.AppendFormat("\t\t\tthis.uiTransform = null;\r\n");
        strBuilder.AppendLine("\t\t}\n");
    }

    private static void CreateDlgWidgetDisposeCode(ref StringBuilder strBuilder, bool isSelf = false)
    {
    
    
        string pointStr = isSelf ? "self" : "this";
        foreach (KeyValuePair<string,List<Component>> pair in Path2WidgetCachedDict)
        {
    
    
            foreach (var info in pair.Value)
            {
    
    
                Component widget = info;
                string strClassType = widget.GetType().ToString();
                string widgetName = widget.name + strClassType.Split('.').ToList().Last();
                strBuilder.AppendFormat("\t\t	{0}.m_{1} = null;\r\n", pointStr, widgetName);
            }
        }
    }

    private static void CreateWidgetBindCode(ref StringBuilder strBuilder, Transform transRoot)
    {
    
    
        foreach (KeyValuePair<string, List<Component>> pair in Path2WidgetCachedDict)
        {
    
    
            foreach (var info in pair.Value)
            {
    
    
                Component widget = info;
                string strPath = GetWidgetPath(widget.transform, transRoot);
                string strClassType = widget.GetType().ToString();
                string strInterfaceType = strClassType;
                string widgetName = widget.name + strClassType.Split('.').ToList().Last();
                strBuilder.AppendFormat("       public {0} {1}\r\n", strInterfaceType, widgetName);
                strBuilder.AppendLine("     {");
                strBuilder.AppendLine("     		get");
                strBuilder.AppendLine("     		{");
                
                strBuilder.AppendFormat("     			if( this.m_{0} == null )\n", widgetName);
                strBuilder.AppendLine("     			{");
                strBuilder.AppendFormat(
                    "		    		this.m_{0} = transform.Find(\"{1}\").GetComponent<{2}>();\r\n",
                    widgetName, strPath, strInterfaceType);
                strBuilder.AppendLine("     			}");
                strBuilder.AppendFormat("     			return this.m_{0};\n", widgetName);
                strBuilder.AppendLine("     		}");
                strBuilder.AppendLine("     	}\n");
            }
        }
    }
    static string GetWidgetPath(Transform obj, Transform root)
    {
    
    
        string path = obj.name;

        while (obj.parent != null && obj.parent != root)
        {
    
    
            obj = obj.transform.parent;
            path = obj.name + "/" + path;
        }

        return path;
    }
    private static void CreateDeclareCode(ref StringBuilder strBuilder)
    {
    
    
        foreach (KeyValuePair<string, List<Component>> pair in Path2WidgetCachedDict)
        {
    
    
            foreach (var info in pair.Value)
            {
    
    
                Component widget = info;
                string strClassType = widget.GetType().ToString();
                string widgetName = widget.name + strClassType.Split('.').ToList().Last();
                strBuilder.AppendFormat("\t\tprivate {0} m_{1}=null;\r\n", strClassType, widgetName);
            }
        }
    }

    /// <summary>
    /// 把所有的组件配置都装好了,装在了Path2WidgetCachedDict
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="strPath"></param>
    private static void FindAllWidgets(Transform trans, string strPath)
    {
    
    
        if (null == trans)
        {
    
    
            return;
        }

        for (int nIndex = 0; nIndex < trans.childCount; ++nIndex) //只算儿子,不算孙子
        {
    
    
            Transform child = trans.GetChild(nIndex);
            string strTemp = strPath + "/" + child.name;
            bool isSubUI = child.name.StartsWith(CommonUIPrefix);

            if (child.name.StartsWith(UIWidgetPrefix))
            {
    
    
                foreach (var uiComponent in WidgetInterfaceList)
                {
    
    
                    Component component = child.GetComponent(uiComponent);
                    if (null == component)
                    {
    
    
                        continue;
                    }

                    if (Path2WidgetCachedDict.ContainsKey(child.name))
                    {
    
    
                        Path2WidgetCachedDict[child.name].Add(component);
                        continue;
                    }

                    List<Component> componentsList = new List<Component>();
                    componentsList.Add(component);
                    Path2WidgetCachedDict.Add(child.name, componentsList);
                }
            }

            if (isSubUI)
            {
    
    
                Debug.Log($"遇到子UI,{
      
      child.name},不生成子UI项代码");
                continue;
            }

            FindAllWidgets(child, strTemp);
        }
    }

 static UICodeSpawner()
    {
    
    
        WidgetInterfaceList = new List<string>();
        WidgetInterfaceList.Add("Button");
        WidgetInterfaceList.Add("Text");
        WidgetInterfaceList.Add("TMP_Text");
        WidgetInterfaceList.Add("InputField");
        WidgetInterfaceList.Add("TMP_InputField");
        WidgetInterfaceList.Add("Dropdown");
        WidgetInterfaceList.Add("TMP_Dropdown");
        WidgetInterfaceList.Add("Input");
        WidgetInterfaceList.Add("Scrollbar");
        WidgetInterfaceList.Add("ToggleGroup");
        WidgetInterfaceList.Add("Toggle");
        WidgetInterfaceList.Add("Slider");
        WidgetInterfaceList.Add("ScrollRect");
        WidgetInterfaceList.Add("Image");
        WidgetInterfaceList.Add("RawImage");
        WidgetInterfaceList.Add("Canvas");
        WidgetInterfaceList.Add("CanvasGroup");
    }

project

Link: https://pan.baidu.com/s/1yToMdgKa1AxsbfWrqu8YMA
extraction code: vabd

Guess you like

Origin blog.csdn.net/weixin_44186849/article/details/128820311