当前位置:   article > 正文

Unity之自动生成预制体脚本_unity代码生成预制体

unity代码生成预制体

在Unity开发中有许许多多的UI界面,包含着不同的组件,比如Button、Image等,我们需要按正确的路径找到它们并持有它们,这个步骤在界面十分庞大的时候,会十分繁琐易错。本文介绍的自动生成代码工具就是为了解决这一困境,可以自动获取那些我们想要的组件,一键生成,希望对你有所帮助。

生成代码展示

在这里插入图片描述

设计思路

我们要使得对象自动生成代码,无非就是分三步,第一步找到这个对象,第二步记录这个对象身上所有需要生成代码的组件,第三步创建一份文件写入我们记录好的内容。

操作流程

  1. 制作好我们需要的预制体界面,要获取组件的对象用T_来开头
  2. 右键界面根节点,点击SpawnUICode(生成UI模板),会弹出操作窗口
  3. 点击窗口的选择脚本要生成的模块,会弹出我们预设的模块下拉菜单,选择我们对应的模块,即可将脚本生成在选中的模块下。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

源码

弹出窗口代码


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);//生成脚本代码
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

内容写入代码

  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");
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218

工程项目

链接:https://pan.baidu.com/s/1yToMdgKa1AxsbfWrqu8YMA
提取码:vabd

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/115308
推荐阅读
相关标签
  

闽ICP备14008679号