Unity Editor实用功能:Hierarchy面板的对象上绘制按按钮并响应

news2024/9/21 20:46:57

目录

  • 需求描述
  • 上代码
  • 打个赏吧

需求描述

现在有这样一个需求:

  • 在Hierarchy面板的对象上绘制按钮
  • 点击按钮,弹出菜单
  • 再点击菜单项目响应自定义操作
  • 在这里的响应主要是复制对象层级路路径
    看具体效果请看动图:
    请添加图片描述

注:

  • 核心是对EditorApplication.hierarchyWindowItemOnGUI委托的实现
  • 其它需求,可参考实现
  • 如是要要Project面板实现类似的功能:可以参考实现EditorApplication.hierarchyWindowItemOnGUI委托

上代码

/**********************************************
 * @author: anyuanlzh
 * @date: 2023-05-18
 * @des:  "Hierarchy面板"工具
 ***********************************************/

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

[InitializeOnLoad]
public class HierarchyTabTool
{
    // 静态构造函数
    static HierarchyTabTool()
    {
      EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
    }
    private static void HierarchyWindowItemOnGUI(int instanceId, Rect selectionRect)
    {
      var obj = EditorUtility.InstanceIDToObject(instanceId) as GameObject;
      if (obj == null)return;
      GameObject selectedObjs = Selection.activeGameObject;
      if(obj!=selectedObjs)return;

      selectionRect.x += selectionRect.width - 60;
      selectionRect.y += 0;
      selectionRect.width = 60f;
      GUIStyle fontStyle = new GUIStyle(GUI.skin.button);
      fontStyle.alignment=TextAnchor.MiddleCenter;
      fontStyle.fontSize=10;
      fontStyle.normal.textColor=Color.yellow;
      //点击事件
      if (GUI.Button(selectionRect, "复制层级", fontStyle))
      {
           // Debug.Log($"click: {Selection.activeObject.name}");
           // 弹出菜单
           Vector2 mousePosition = Event.current.mousePosition;
           Rect position = new Rect(mousePosition.x, mousePosition.y+7, 0, 0);
           EditorUtility.DisplayPopupMenu(position, "GameObject/1_复制层级路径", null);
      }
    }

	// 防止一次点击响应多次
    private static float _last_call_time = 0;
    private static float minInterval_time = 0.5f;

    [MenuItem("GameObject/1_复制层级路径/A点~B点", false, 40)]
    private static void GetHierarchyPath2()
    {
      if (Time.time - _last_call_time<minInterval_time)
      {
           return;
      }
      _last_call_time = Time.time;

      GameObject[] selectedObjs = Selection.gameObjects;
      //Debug.Log(selectedObjs.Length);
      if (selectedObjs.Length == 1)
      {
           Copy_HierarchyPath_root2target();
           return;
      }
      else if (selectedObjs.Length < 2)
      {
           Debug.Log("请选择一个或二个有包含关系对象");
           return;
      }

      Transform first = selectedObjs[0].transform;
      Transform last = selectedObjs[selectedObjs.Length-1].transform;
      // Debug.Log($"first.name:{first.name} last.name:{last.name}");
      Transform a = null;
      Transform b = null;
      if (EditorUtils.IsAncestor(first, last))
      {
           a = first;
           b = last;
      }
      else if (EditorUtils.IsAncestor(last, first))
      {
           a = last;
           b = first;
      }
      else
      {
           Debug.LogError("请选择有包含关系的二个对象");
           return;
      }

      List<string> names = new List<string>();
      while (b!=null)
      {
           if (a == b)
           {
                names.Insert(0,b.name);
                break;
           }
           names.Insert(0, b.name);
           b = b.parent;
      }
      string path = "";
      for (int i = 0; i < names.Count-1; i++)
      {
           path += names[i] + "/";
      }
      path += names[^1];
      GUIUtility.systemCopyBuffer = path;
      Debug.Log("对象层次路径 A点到B点: " + path);
    }

    [MenuItem("GameObject/1_复制层级路径/根0~目标", false, 40)]
    private static void Copy_HierarchyPath_root0target()
    {
      Copy_HierarchyPath_rootN2target(0);
    }
    [MenuItem("GameObject/1_复制层级路径/根1~目标", false, 40)]
    private static void Copy_HierarchyPath_root1target()
    {
      Copy_HierarchyPath_rootN2target(1);
    }
    [MenuItem("GameObject/1_复制层级路径/根2~目标", false, 40)]
    private static void Copy_HierarchyPath_root2target()
    {
      Copy_HierarchyPath_rootN2target(2);
    }
    [MenuItem("GameObject/1_复制层级路径/根3~目标", false, 40)]
    private static void Copy_HierarchyPath_root3target()
    {
      Copy_HierarchyPath_rootN2target(3);
    }
    // 从根0的第N级到目标
    // rootN从零开
    static void Copy_HierarchyPath_rootN2target(int rootN)
    {
      if (Time.time - _last_call_time<minInterval_time)
      {
           return;
      }
      _last_call_time = Time.time;

      if (Selection.count != 1)
      {
           Debug.LogError($"Copy_HierarchyPath_rootN2target: 请选择一个对象");
           return;
      }

      Transform target = Selection.activeGameObject.transform;
      List<string> names = new List<string>();
      Transform parent = target.transform.parent;
      while (target != null)
      {
           names.Insert(0, target.name);
           target = target.parent;
      }
      if (names.Count - 1 < rootN)
      {
           Debug.LogError($"Copy_HierarchyPath_rootN2target: N:{rootN}大于目标对象的深度");
           return;
      }

      string path = "";
      for (int i = rootN; i < names.Count-1; i++)
      {
           path += names[i] + "/";
      }
      path += names[^1];
      GUIUtility.systemCopyBuffer = path;
      Debug.Log($"对象层次路径 root_{rootN}到target:" + path);
    }
}

打个赏吧

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1369505.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

歌手荆涛演唱的春节回家:传统与现代的交织,歌声里的乡愁与期盼

随着冬日渐寒&#xff0c;春节的脚步愈发临近。这是一个充满温馨与期待的时刻&#xff0c;一个穿越时空、凝聚亿万华夏儿女情感的盛大节日。春节&#xff0c;它不仅仅是一个传统习俗的展现&#xff0c;更是一种心灵的归宿&#xff0c;一种文化的传承。 在悠久的历史长河中&…

一文掌握文本语义分割:从朴素切分、Cross-Segment到阿里SeqModel

前言 之所以写本文&#xff0c;源于以下两点 在此文《基于LangChainLLM的本地知识库问答&#xff1a;从企业单文档问答到批量文档问答》的3.5节中&#xff0c;我们曾分析过langchain-chatchat项目中文本分割相关的代码&#xff0c;当时曾提到该项目中的文档语义分割模型为达摩…

SUDA-计算机网路-期末复习提纲

写在前面 帮苏大的同学整理的计网复习材料&#xff0c;用的是他们老师划定的范围。 1.负责互联网协议开发、标准制定、地址分配的国际组织名称及其主要职责 (1) 地址支持组织&#xff08;ASO&#xff09;负责IP地址系统的管理。 (2) 域名支持组织&#xff08;DNSO&#xff09;…

【HarmonyOS4.0】第三篇-类web开发模式

【HarmonyOS4.0】第三篇-类web开发模式 一、鸿蒙介绍 课程核心 为什么我们需要学习鸿蒙&#xff1f; 哪些人适合直接转鸿蒙&#xff1f; 鸿蒙系统优势是什么&#xff1f; 课程内容 (1)为什么要学习鸿蒙 从行情出发&#xff1a; 美国商务部长访问中国&#xff0c;2023年…

众和策略:沪指跌0.91%险守2900点,半导体、金融等板块走低

8日早盘&#xff0c;两市股指低开低走&#xff0c;沪指一度失守2900点&#xff0c;深成指、创业板指跌约1%&#xff0c;科创50指数创前史新低。 到午间收盘&#xff0c;沪指跌0.91%报2902.4点&#xff0c;深成指跌1.17%&#xff0c;创业板指跌0.99%&#xff0c;科创50指数跌超…

视频剪辑技巧:快速批量修改视频分辨率,高效剪辑修改尺寸的方法

随着视频内容的普及&#xff0c;经常要处理大量的视频文件。在这个过程中&#xff0c;视频分辨率的修改是一个常见的需求。无论是适应不同的播放平台&#xff0c;还是满足特定的视觉要求&#xff0c;调整视频分辨率是必不可少的步骤。但逐个手动调整不仅效率低下&#xff0c;而…

Python处理字符串-正则提取遇到的第一个完整括号内容处理后替换

1.场景分析 该场景介绍如何用python语言&#xff0c;使用正则表达式处理字符串内第一个完整的括号内容&#xff0c;一个括号内可能会含有一个括号&#xff0c;多个括号自行扩展正则即可&#xff0c;处理完成后再替换到括号的内容 2.重难点 第一个括号内可能会还有另一个括号 …

jmeter循环控制器

1.循环控制器 简单粗暴 写几次 循环几次 经常结合自定义变量使用 2.foreach控制器 搭配 变量一起使用的循环 一般变量的值是一个集合或者 是2个及2个以上的内容

Python 使用input函数从键盘输入数据

在Python中&#xff0c;input()函数可以从键盘获取用户的输入数据。当我们使用input()函数时&#xff0c;会暂停程序的执行&#xff0c;等待用户输入数据&#xff0c;并将用户输入的数据作为字符串返回。 如&#xff1a; name input("请输入你的姓名&#xff1a;"…

尝试使用深度学习识别百度旋转验证码

最近研究了一下图像识别&#xff0c;一直找到很好的应用场景&#xff0c;今天我就发现可以用百度的旋转验证码来做一个实验。没想到效果还挺好&#xff0c;下面就是实际的识别效果。 1、效果演示 2、如何识别 2.1准备数据集 首先需要使用爬虫&#xff0c;对验证码图片进行采…

数据结构(2023-2024)

一、判断题 1.队列是一种插入和删除操作分别在表的两端进行的线性表&#xff0c;是一种先进后出的结构。&#xff08;F&#xff09; 队列先进先出&#xff0c;在表的一端插入元素&#xff0c;在表的另一端删除元素。允许插入的一端称为队尾&#xff08;rear&#xff09;&#…

基于 SpringBoot + vue 的医院管理系统(含源码,数据库,文档)

基于 SpringBoot vue 的医院管理系统 †前后端分离思想&#xff0c;这个系统简直太棒了&#xff01;屯 光这个系统采用了 前后端分离思想&#xff0c;后端使用 SpringBoot和 SpringMVC框架&#xff0c;让代码更高效&#xff0c;更易于维护。前端则使用了 vue js 和ElementU…

Unity 利用UGUI之Scrollbar制作进度条

在Unity中除了用Slider、Image做进度条&#xff0c;其实用Scrollbar也可以做进度条。 首先&#xff0c;在场景中新建一个Scrollbar组件和一个Text组件&#xff1a; 其次&#xff0c;创建模拟进度的一个脚本&#xff0c;Scrollbar_Progressbar.cs: using System.Collections; …

有些应用中不需要使用回原点指令

不是所有的轴运动控制&#xff0c;都一定要使用回原点指令来执行回原点 通过手动找到极限开关&#xff0c;然后往回走一段距离&#xff0c;也是一种方式&#xff0c;所谓的往回走的这段距离方便用于手动校准原点位置&#xff1b; 那使用原点指令回原点后&#xff0c;也可以走一…

Python异步编程|PySimpleGUI界面读取PDF转换Excel

目录 实例要求 原始pdf文件格式 输出xls文件格式 运行界面 完整代码 代码分析 遍历表格 布局界面 控件简介 写入表格 表格排序 事件循环 异步编程 实例要求 使用PySimpleGUI做一个把单位考勤系统导出的pdf文件合并输出Excel的应用&#xff0c;故事出自&#xff1…

Java web设计:在线微友圈网站

项目背景 微友圈是一个基于Java Web开发的社交网络平台&#xff0c;旨在为用户提供一个轻松互动、分享生活和交流观点的在线社区。随着社交网络的普及&#xff0c;人们更加渴望与朋友、家人以及其他志同道合的人保持联系并分享彼此的生活点滴。微友圈的目标是打造一个简洁、高…

nn网络层-卷积层

一、1d/2d/3d Convolution 卷积运算&#xff1a;卷积核在输入信号&#xff08;图像&#xff09;上滑动&#xff0c;相应位置上进行乘加卷积核&#xff1a;又称为滤波器&#xff0c;过滤器&#xff0c;可认为是某种模式&#xff0c;某种特征。卷积过程类似于用一个模版去图像上…

OpenAI ChatGPT-4开发笔记2024-01:开发环境

ChatGPT发展一日千里。工具、函数少则数日&#xff0c;多则数月就加入了Deprecated行列不再如预期般工作。元旦闲来无事&#xff0c;用最新的ChatGPT重写一下各种开发场景&#xff0c;全部实测通过。 开发环境&#xff1a; 电脑&#xff1a;两台笔记本&#xff1a;HP和MacBoo…

AI-数学-高中-3.二次函数的根的分布问题的解题方法

原作者学习视频&#xff1a;二次】3二次函数根分布问题&#xff08;中档&#xff09;_哔哩哔哩_bilibili 一、伟达定理&#xff08;根与0比较的二次函数&#xff09; 示例&#xff1a; 二、画图法&#xff1a; 1.开口方向的确定&#xff0c;有的示例可能存在向上、下两种情况…

顺序栈之共享栈实现——C语言

参考书&#xff1a;数据结构教程 第5版 李葆春 P83 #include <stdio.h> #include <string.h> #include <stdlib.h>#define MaxSize 10/*共享栈*/ typedef struct {char data[MaxSize];int top1,top2,len; }DStack;/*初始化*/ void InitStack(DStack *s){s-…