Unity之自动生成预制体脚本

这篇具有很好参考价值的文章主要介绍了Unity之自动生成预制体脚本。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

生成代码展示

unity代码生成预制体,Unity功能,unity,ui,游戏引擎,自动生成代码,UI工具

设计思路

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

操作流程

  1. 制作好我们需要的预制体界面,要获取组件的对象用T_来开头
  2. 右键界面根节点,点击SpawnUICode(生成UI模板),会弹出操作窗口
  3. 点击窗口的选择脚本要生成的模块,会弹出我们预设的模块下拉菜单,选择我们对应的模块,即可将脚本生成在选中的模块下。
    unity代码生成预制体,Unity功能,unity,ui,游戏引擎,自动生成代码,UI工具
    unity代码生成预制体,Unity功能,unity,ui,游戏引擎,自动生成代码,UI工具
    unity代码生成预制体,Unity功能,unity,ui,游戏引擎,自动生成代码,UI工具

源码

弹出窗口代码


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文章来源地址https://www.toymoban.com/news/detail-517807.html

到了这里,关于Unity之自动生成预制体脚本的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 源生成器:根据需要自动生成机械重复代码

    本文概述了利用.NET Compiler Platform(“Roslyn”)SDK 附带的 源生成器 (Source Generator)自动生成机械重复的代码。关于这部分的基础入门知识可以在MSDN [1] 学到。 本文 默认 已经有一个解决方案,包含两个项目。一个是普通C#项目,依赖于另一个源生成器项目。 此处以 Dependenc

    2024年02月01日
    浏览(73)
  • AIGC for code(text-to-codeAIGC/AI生成代码/生成式AI之代码生成/AI编程工具/自动编程/自动生成代码/智能编程工具/智能编程系统)

    AIGC,Artificial Intelligence Generated Content,人工智能生成内容 AIGC for code,AI生成代码 Copilot是由微软的子公司Github与openAI共同开发的人工智能(AI)驱动的编程助手。它能够直接在你的编辑器中,为你提供代码片段或者整个函数的建议,以帮助你更快地编写和完成代码。这个工具

    2024年02月15日
    浏览(58)
  • Unity SpriteAtlas(图集)自动生成工具

    图集是一种将多个纹理合并为一个组合纹理的资源。 可以调用此单个纹理来发出单个绘制调用而不是发出多个绘制调用,能够以较小的性能开销一次性访问压缩的纹理 减少DrawCall,一张图集只需要一次DrawCall 图集将一张或者多张图片合成一张2的幂次方的图片,减少资源大小

    2024年02月13日
    浏览(50)
  • AI自动生成代码工具

    AI自动生成代码工具是一种利用人工智能技术来辅助或自动化软件开发过程中的编码任务的工具。这些工具使用机器学习和自然语言处理等技术,根据开发者的需求生成相应的源代码。以下是一些常见的AI自动生成代码工具,希望对大家有所帮助。北京木奇移动技术有限公司,

    2024年02月04日
    浏览(42)
  • 13.若依代码自动生成功能详解

    基于若依的目录结构,若依本身提供了代码生成功能,可以根据数据库表的内容,生成一些基本的CRUD的前后端的功能。本文将生成过程中的一些注意事项,进行了整理和说明 注意:在使用代码生成功能之前,一定要注意数据库字段,不能是,要不使用的时候,一堆问

    2024年01月25日
    浏览(47)
  • 代码自动生成工具——TableGo(实例演示)

            在SpringBoot项目开发中,为了提高开发效率,我们经常需要使用代码自动生成工具来生成一些重复性的代码,比如实体类、DAO、Service、Controller等等。下面介绍几个常用的代码自动生成工具: ①、MyBatis Generator         MyBatis Generator是由MyBatis官方提供的一个代码

    2024年02月07日
    浏览(44)
  • 工具—IDEA代码自动生成插件EasyCode

    官网简介 基于IntelliJ IDEA开发的代码生成插件,支持自定义任意模板(Java,html,js,xml)。 只要是与数据库相关的代码都可以通过自定义模板来生成。支持数据库类型与java类型映射关系配置。 支持同时生成生成多张表的代码。每张表有独立的配置信息。完全的个性化定义,

    2024年02月09日
    浏览(42)
  • 帝国CMS自动生成缩略图和自动分页功能代码

    自动生成缩略图代码 \\\'; 无论你手工发布,还是采集而来,免不了要进行手工操作弄缩略图,不然标题图片没有,挺烦人的 只需一次设定,就可以在文章编辑框里自动勾选上分页和生成缩略图,免除你次次进行操作的麻烦,好了,废话不多说,上菜“ 先到 系统管理数据表 后

    2024年02月03日
    浏览(60)
  • 体验一波ChatGpt工具-cursor(自动代码生成)

    最近体验了一把cursor,自动生成代码工具,集成了最近很火的ChatGpt,目前比较好的就是代码生成工具大概就是github copilot和cursor,不过github copilot需要付费使用或者漫长的waitlist,所以目前比较好的cursor 官网介绍如下: 配置自己经常使用的语言,比如ts、html、css等等 目前来说

    2023年04月21日
    浏览(69)
  • 深入拆解Simulink自动生成代码(三)——循环结构

    前言 一、Simulink实现循环结构 二、自动生成C代码 三、变式1 四、变式2 五、变式3 六、变式4 总结         《深入拆解Simulink自动生成代码(一)——数据流处理》         《深入拆解Simulink自动生成代码(二)——选择结构》          用Simulink实现循环结构的一个

    2024年02月12日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包