在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(); //初始化GenericMenufor (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

Unity之自动生成预制体脚本相关推荐

  1. 【Unity3D日常开发】生成预制体,并且预制体自动销毁

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 一.前言 今天有粉丝问我一个很简单的问题,如何生成预制体,并且让预制体自动销 ...

  2. unity动态生成预制体

    public void GameObjectPrefab(GameObject Prefab){PrefabUtility.SaveAsPrefabAsset(Prefab, "Assets ...

  3. Unity使用c#开发遇上的问题(六)(3dmax围绕指定中心旋转,unity中动态调用预制体并根据模型旋转指定角度)

    文章目录 前言 一.3dmax创建子弹.炮塔及武器库 1.相关模型 2.炮塔模型引入unity,无法绕旋转球旋转,重新调整 1.3dmax中默认炮管的中心点 2.选择层次界面 3.选择编辑工作轴 4. ...

  4. 根据Word表格自动生成SQL数据库脚本的VBScript代码

    这是几年前写的根据Word表格自动生成SQL数据库脚本的VBScript代码,最近修改了下(原来只支持单个Word表格)使其支持一个Word文档中的多个表格,生成的SQL文件名以Word文件名+.SQ ...

  5. Unity代码自动生成

    这里举两个简单的例子(非原创,不选原创发布不了) 第一个例子是知乎上的例子: https://zhuanlan.zhihu.com/p/30716595 自动给UI组件绑定 第二个例子是自己的需求,需 ...

  6. 自动生成卡密SQL脚本(转载)

    Comments - 446 自动生成卡密SQL脚本(转载) Code if exists (select * from dbo.sysobjects where id = object_id(N'[ ...

  7. Unity 将图片做成预制体

    Unity 将图片做成预制体 刚导入Assets的图片是无法直接拖入场景中的,若我们想要将图片变成预制体,需要做一点转化. 方法如下: 选中想要转成预制体的图片,更改如下图: 然后就可以将图片拖入场景 ...

  8. Unity编辑器扩展——自动生成UI界面脚本

    一:前言 对于面板赋值或Find绑定UI组件,我们可以使用一种工具化的方式去自动生成代码并绑定对象,增加效率 分为logic和view,view层是UI界面上的组件,每次都会自动生成并覆盖,logic ...

  9. 【Unity入门】21.预制体

    [Unity入门]预制体     大家好,我是Lampard~~     欢迎来到Unity入门系列博客,所学知识来自B站阿发老师~感谢  (一)预制体制作 (1)什么是预制体     这一章节的博客 ...

最新文章

  1. Supervisor进程管理开机自启
  2. JQuery与CSS相结合的下拉框
  3. EventTrigger接管所有事件导致其他事件无法触发
  4. 本地连接的图标要等很长时间才出来
  5. 全球品牌百强榜单出炉:中国品牌仅有华为上榜
  6. 实验二 动态规划算法 最长公共子序列问题
  7. 5g鸿蒙概念,华为5G概念机,真全面屏+鸿蒙系统,颜值再登巅峰
  8. 安装Docker,配置阿里云加速和 docker-compose 国内镜像
  9. 苹果Mac桌面Dock中App icon 名称显示乱码怎么办?一个简单指令帮你解决
  10. 利用POI将PPT转换为图片
  11. TensorRT学习(1):通过pth生成wts文件
  12. 漫反射贴图与镜面光贴图
  13. Open JDK patched with font fix
  14. 设置电脑保护视力的颜色
  15. winform listbox控件简单使用。
  16. 清晰理解红黑树的演变---红黑的含义
  17. 内部总线(双向数据总线)
  18. 鸟人的Android揭秘(8)——搭建Android SDK开发环境(四)
  19. 分享6个教师常用的网站,再也不用到处找资源了
  20. qt中新增html,Qt和HTML笔记:初始化

热门文章

  1. Java小农养成记第八天
  2. 微型计算机中内存比外存怎样,在同一台计算机中,内存比外存( )。
  3. PyCharm 2022.2 发布了,支持最新 Python 3.11 和 PyScript 框架!
  4. DirectX12(D3D12)基础教程(二十)—— 纹理数组(Texture Array)非DDS初始化操作
  5. 等保测评--工业控制系统安全扩展要求
  6. 【干货】python xlwt写入excel操作
  7. Unitree Go1——开发指南
  8. 计算机 小学数学应用题教学设计,小学数学如何有效地进行应用题教学设计
  9. 使用 Learner Lab - 如何设置自己想要的VPC,以供EC2使用
  10. 基于语义分割的身份证部件解析和文字检测