Unity UGUI一键绑定UI控件工具(编辑器拓展)

这篇具有很好参考价值的文章主要介绍了Unity UGUI一键绑定UI控件工具(编辑器拓展)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

效果

Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎

Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎

全为一键生成

实现自动生成代码绑定UI控件 并生成字典保存UI控件

减少自己拖拽 和手动书写过程 适用动态加载面板

建议搭配UI框架使用

实现思路

根据当前选中的gameobject 查找其下方是否有对应类型的控件 有就保存到字典中 然后通过向上递归拼凑地址,然后生成到粘贴板 直接粘贴到目标位置即可

实现过程

Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎Selection.gameObjects会获取当前选中的物体数组 我们取出第一个即可

Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎

这个字典专门用来存放 我们需要获取的类型和该类型在代码里面的前缀

如 名字叫  AddButton的物体身上的button组件 获取后在代码里面的名字为  btnAddbutton

Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎

根据刚才字典的键,就是我们要获取的类型 遍历选中物体下所有子物体是否有该类型的组件 有就存放到字典 改字典的 键是

该控件物体的地址如 Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎

值是控件类型Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎

至于为什么要这样做后面会解释

Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎

找到当前foreach循环类型的组件后 会保存到component数组里面 开始拼凑地址 凑地址之前会进行判断 如果后缀 不是自定义的字符串 就不进行生成Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎

这样增加灵活性

然后开始拼凑当前component[i]的地址

(清除后缀  如LoadPlace_Auto会切割为 LoadPlace作为真实名字保存为临时变量 在声明变量时使用)

思路是while循环 当父物体不为选中物体是就一直向上循环拼凑字符串

加入字典的时候为什么要把键 设置为简称加上地址呢

因为如果键是地址的话 如果这个物体上同时拥有 image和text那键就重复了 都是xxx/xxx/xxx

所有改成简称加上地址  这样找到的image在字典中就是  imgxxx/xxx/xxx  不会重复

完成循环后 我们的字典里面已经找到了所有我们需要自动绑定的UI控件

键值对形式为  控件检测+地址,真实控件实例

然后开始生成代码

Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎

通过/来分割字符串 获取字符串的最后一位

Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎LoadPlace_auto这个物体的上的image组件 的键就为  imgLeft/CargoShow/LoadPlace_Auto 

我们直接用/切割字符串

获取最后一位 即LoadPlace_Auto 

这样不会出现问题

但如果LoadPlace_Auto 在选中的PlaningPanel下面第一位

键就会变为imgLoadPlace_Auto 这样/切割就会失效 会出bug

所以我们加一个判断 如果切割后只有一位长度 那就要去除前缀

这样才能拿到真实的名字

Unity UGUI一键绑定UI控件工具(编辑器拓展),unity,ui,游戏引擎

切割到前面的前缀 获取真实的地址

根据我们的命名规则 拼凑代码中的命名

然后生成到粘贴板即可文章来源地址https://www.toymoban.com/news/detail-855792.html

代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using UnityEngine.UI;
using System.Text;
using TMPro;

public class UIBindingTool : Editor
{
    private static string endWith = "_Auto";
    /// <summary>
    /// 简称+真实地址  类型
    /// </summary>
    private static Dictionary<string, Type> findDic = new Dictionary<string, Type>();//保存已经找到的控件 类型名字简称+真实地址 类型 原因防止key重复并且都是3位好处理
    private static Dictionary<Type, string> dicMap = GenerateBtuDic();
    [MenuItem("GameObject/GenerateBinding", false, 1)]
    private static void GenerateBinding()
    {

        if (Selection.gameObjects.Length < 1)//返回当前在Hierarchy面板上或Project文件夹下选择的游戏物体GameObject数组,未选择则数组长度则为0
            return;
        GameObject selectObj = Selection.gameObjects[0];//找到选中的第一个物体
                                                        //foreach (var item in Selection.gameObjects)
                                                        //{
                                                        //    Debug.Log(item.name);
                                                        //}
                                                        //if (dicMap == null) ;
                                                        //Dictionary<Type, string> dicMap = GenerateBtuDic();//控件类型对应的名字字典


        StringBuilder pasteContent = new StringBuilder();
        //声明保存的字典 
        //rider不要\t
        // pasteContent.Append("\t#region 自动绑定\n");
        pasteContent.Append("#region 自动绑定\n");
        pasteContent.Append("\tprivate Dictionary<string, UIBehaviour> componentsDic = new Dictionary<string, UIBehaviour>();\n");
        foreach (Type type in dicMap.Keys)//看看物体上有没有对应类型的控件 keys是UI组件类型
        {
            //获取子物体上所有对应UI组件
            Component[] components = selectObj.GetComponentsInChildren(type);//GetComponentsInChildren可以获取到儿子孙子 深度优先 包含自己
            if (components.Length < 1) continue;//没有获取到就下一个
            for (int i = 0; i < components.Length; i++)
            {
                //if (!components[i].name.StartsWith(startsWith))
                if (!components[i].name.EndsWith(endWith))
                    continue;// 加一个字符串条件判断
                //满足条件
                Component component = components[i];

                //组件的名字
                string name = dicMap[type] + component.name.Substring(0, component.name.Length - endWith.Length);
                //组件的地址 
                string path = component.name;
                Transform transform = component.transform;
                //构成控件的path
                while (!transform.parent.name.Equals(selectObj.name))//中间的地址
                {
                    //Debug.Log(transform.name);
                    path = transform.parent.name + "/" + path;
                    transform = transform.parent;
                }
                //地址=父物体名字+中间地址+名字
                //Debug.Log(selectObj.name +"/"+ path);
                findDic.Add(dicMap[type] + /*selectObj.name + "/" +*/ path, type);
                //Debug.Log(dicMap[type] + /*selectObj.name + "/" +*/ path);
                //组件的声明
                pasteContent.Append("\t"+"private" + "\t" + type.Name + "\t" + name + ";");
                pasteContent.Append("\n");

            }
            //Debug.Log(pasteContent);

        }
        pasteContent.Append("\t#endregion\n");
        //查找组件
        pasteContent.Append("\t//自动获取组件添加字典管理");
        pasteContent.Append("\n");
        pasteContent.Append("\tprivate void AutoBindingUI()");
        pasteContent.Append("\n");
        pasteContent.Append("\t{");
        foreach (string item in findDic.Keys)
        {
            //!!!直接在选中物体下面的会有Bug!!!  如果一共就一位 先去掉前缀再继续
            string[] temp = item.Split("/");
            string componentName;
            if (temp.Length > 1)
                //获取真实名字
                componentName = temp[temp.Length - 1];
            else
                componentName = temp[temp.Length - 1].Substring(dicMap[findDic[item]].Length);


            //获取真实地址 Bug
            string realPath = item.Substring(dicMap[findDic[item]].Length);


            //拼接变量名
            string varName = dicMap[findDic[item]] + componentName.Substring(0, componentName.Length - endWith.Length);
            //Debug.Log(componentName.Substring(0, componentName.Length - endWith.Length));
            //Debug.Log(componentName + " " + realPath + " " + varName);
            //语句
            pasteContent.Append("\n");
            pasteContent.Append($"\t\t{varName} = transform.Find(\"{realPath}\").GetComponent<{findDic[item].Name}>();");
            //rigidbody = transform.Find().GetComponent<>();

        }
        //加入字典
        foreach (string item in findDic.Keys)
        {
            //!!!直接在选中物体下面的会有Bug!!!  如果一共就一位 先去掉前缀再继续

            string[] temp = item.Split("/");
            string componentName;
            if (temp.Length > 1)
                //获取真实名字
                componentName = temp[temp.Length - 1];
            else
                componentName = temp[temp.Length - 1].Substring(dicMap[findDic[item]].Length);
            //拼接变量名
            string varName = dicMap[findDic[item]] + componentName.Substring(0, componentName.Length - endWith.Length);
            //Debug.Log(componentName.Substring(0, componentName.Length - endWith.Length));
            //Debug.Log(componentName + " " + realPath + " " + varName);
            //语句
            pasteContent.Append("\n");
            pasteContent.Append($"\t\tcomponentsDic.Add(\"{varName.ToString()}\", {varName});");
            //componentsDic.Add(inputPlaneID.ToString(), inputPlaneID);

        }
        //TODO:生成封装组件事件的方法
        pasteContent.Append("\n");
        pasteContent.Append("\t}");
        TextEditor text = new TextEditor();

        text.text = pasteContent.ToString();
        text.SelectAll();
        text.Copy();
        Debug.Log("生成成功");
    }
    private static Dictionary<Type, string> GenerateBtuDic()//寻找里面有没有我定义的类型的键(key)匹配,然后返回我对应的类型?
    {
        Dictionary<Type, string> dic = new Dictionary<Type, string>();
        dic.Add(typeof(Button), "btn");
        dic.Add(typeof(Scrollbar), "scrB");
        dic.Add(typeof(Image), "img");
        dic.Add(typeof(TMP_InputField), "input");
        dic.Add(typeof(VerticalLayoutGroup), "layoutGRP");
        dic.Add(typeof(Text), "text");
        dic.Add(typeof(TMP_Text), "texT");
        dic.Add(typeof(GridLayoutGroup), "layout");
        dic.Add(typeof(TMP_Dropdown), "dropD");
        return dic;
    }


}

到了这里,关于Unity UGUI一键绑定UI控件工具(编辑器拓展)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Unity 编辑器-创建模板脚本,并自动绑定属性,添加点击事件

    当使用框架开发时,Prefab挂载的很多脚本都有固定的格式。从Unity的基础模板创建cs文件,再修改到应有的模板,会浪费一些时间。尤其是有大量的不同界面时,每个都改一遍,浪费时间不说,还有可能遗漏或错改。写个脚本创建指定的模板代替C#基础模板。 注:当前脚本使用

    2024年02月13日
    浏览(63)
  • Unity编辑器实现对选中物体一键替换材质

           最近美术同事在整理模型动画时有一个需求,就是选中部分的模型一件将材质替换成同一个材质球。在编辑器下将这个功能实现了出来。代码放在最后,简单记录一下。 首先对选中进行遍历,拿到所有的子对象; 对每个具体的对象拿到对应的 Mesh Renderer 组件; 对每

    2024年02月13日
    浏览(58)
  • 了解Unity编辑器之组件篇UI(一)

    UI组件:提供了用户交互,信息展示,用户导航等功能 一、Button: 用于响应用户的点击事件 1.Interactable(可交互):该属性控制按钮是否可以与用户交互,如果禁用则按钮无法被点击。可以通过脚本动态修改该属性。 2.Transition(过渡效果):该属性定义了按钮状态切换时的

    2024年02月16日
    浏览(65)
  • Unity编辑器扩展——自动生成UI界面脚本

    一:前言 对于面板赋值或Find绑定UI组件,我们可以使用一种工具化的方式去自动生成代码并绑定对象,增加效率 分为logic和view,view层是UI界面上的组件,每次都会自动生成并覆盖,logic层是逻辑 二:使用 例如一个UI界面,我们只需要做成预制体并在Project下右键预制体,选择

    2024年02月11日
    浏览(47)
  • 盘点Unity几款编辑器扩展工具

    unity 编辑器一个不容忽视的强大之处就是非常易于自定义扩展工具,来满足各种各样的美术、策划及程序上的需求。今天为大家介绍Asset Store资源商店中几款实用的编辑器扩展工具,帮助大家直接在Unity编辑器中完成3D建模与调整工作,免去与其它软件进行数据转换的过程,从

    2024年04月09日
    浏览(49)
  • Unity 编辑器工具之批量设置图片压缩

    一个简单的工具,对Unity下的图片做批量压缩处理,主要有以下功能: 自动取消 \\\"Generte Mip Maps\\\" 勾选; 针对文件夹批量自动(或手动选择压缩格式)设置图片压缩并自动保存; 单个图片文件的压缩设置; 使用方法,右键单张图片(或者包含图片的文件夹) 会打开一个设置窗口 如下,窗口里会

    2024年02月10日
    浏览(48)
  • 【Unity UIToolkit】UIBuilder基础教程-制作简易的对话系统编辑器 3步教你玩转Unity编辑器扩展工具

    随着Unity开发的深入,基本的Unity编辑器界面并不能满足大部分玩家高阶开发的要求。为了提高开发的效率,有针对性的定制化扩展编辑器界面是提高开发效率的不错选择。 今天就给大家带来Unity官方提高的编辑器扩展工具UIToolkit(集成了UIBuilder和UI Debugger等插件)的使用教程。

    2024年02月04日
    浏览(72)
  • Unity Shader编辑器工具类ShaderUtil 常用函数和用法

    Unity的Shader编辑器工具类ShaderUtil提供了一系列函数,用于编译、导入和管理着色器。本文将介绍ShaderUtil类中的常用函数和用法。 函数签名: public static bool CompileShader(string source, out string error); CompileShader函数用于编译一个着色器。它接受一个字符串参数source,表示要编译的着

    2024年02月14日
    浏览(36)
  • Unity 编辑器预制体工具类PrefabUtility 常用函数和用法

    在Unity中,预制体(Prefab)是一种非常有用的工具,它允许我们创建可重复使用的对象和场景元素。Unity提供了许多内置的工具和函数来处理预制体,其中一个重要的类就是PrefabUtility。PrefabUtility类提供了一系列函数,用于创建、实例化和管理预制体。在本文中,我们将介绍

    2024年02月14日
    浏览(45)
  • Unity 编辑器选择器工具类Selection 常用函数和用法

    点击封面跳转下载页面 在Unity中,Selection类是一个非常有用的工具类,它提供了许多函数和属性,用于操作和管理编辑器中的选择对象。本文将介绍Selection类的常用函数和用法,并提供相应的示例代码。 功能: 获取或设置当前活动的上下文对象。 示例代码: 功能: 获取或

    2024年02月14日
    浏览(47)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包