赞
踩
在Unity开发中有许许多多的UI界面,包含着不同的组件,比如Button、Image等,我们需要按正确的路径找到它们并持有它们,这个步骤在界面十分庞大的时候,会十分繁琐易错。本文介绍的自动生成代码工具就是为了解决这一困境,可以自动获取那些我们想要的组件,一键生成,希望对你有所帮助。
我们要使得对象自动生成代码,无非就是分三步,第一步找到这个对象,第二步记录这个对象身上所有需要生成代码的组件,第三步创建一份文件写入我们记录好的内容。
弹出窗口代码
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);//生成脚本代码 } }
内容写入代码
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"); }
链接:https://pan.baidu.com/s/1yToMdgKa1AxsbfWrqu8YMA
提取码:vabd
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。