Unity 两篇文章熟悉所有编辑器拓展关键类 (上)

         本专栏基础资源来自唐老狮和siki学院,仅作学习交流使用,不作任何商业用途,吃水不忘打井人,谨遵教诲

         编辑器扩展内容实在是太多太多了(本篇就有五千字++)

        所以分为两个篇章而且只用一些常用api举例,更多的还是起到留下学习印象的作用

        就像引用类型的堆和栈一样,本文提供栈的作用,指向的内存堆为官方文档

什么是编辑器扩展

        Unity编辑器扩展是指通过编写自定义脚本和插件,利用Unity提供的API来增强和扩展Unity编辑器的功能,这些扩展可以显著提高开发效率和灵活性 

        前置知识:GUI 

        可能需要熟悉的知识: EditorGUI - Unity 脚本 API

     大部分的编辑器扩展脚本都需要写在Editor文件中,这样unity打包的时候,不会打包出去该文件

1.MenuItem类

作用:在unity未运行时 一键使用自定义静态函数

MenuItem - Unity 脚本 API --- MenuItem - Unity 脚本 API

1.创建菜单栏

 [MenuItem("扩展菜单名/一级菜单名/方法名任意")] 菜单级数任意

实现效果如下

引入命名空间,函数必须为静态函数

using UnityEngine;
public class T1 
{
   //在unity不同的地方一键执行静态函数
   [MenuItem("扩展菜单名/TestMethod/Function1")]
   public static void Function1(){
        Debug.Log("输出任意一句话");
    }
}

可以添加特殊标识符,在不同的窗口创建使用,而不只是通过菜单栏中去选择

类似这样

总结一下规则如下图

2.绑定快捷键规则 

3.在组件菜单中拓展自定义脚本

[AddComponentMenu("一级菜单/二级菜单/脚本名建议和实际脚本一致")] 菜单级数任意

众所周知 ,在unity中脚本就可以理解为组件

所以在菜单栏中的组件菜单中,是可以将自定义的脚本添加进去的

使用特性AddComponentMenu: 

//在组件菜单中添加 自定义脚本(组件)
[AddComponentMenu("一级菜单/二级菜单/脚本名")]
public class T2 : MonoBehaviour
{
 
}

选中物品就可以添加了

4.为脚本添加使用自定义函数

[MenuItem("CONTEXT/脚本名/一级菜单名/函数名任意")]  菜单级数任意

//在组件菜单中添加 自定义脚本(组件)
[AddComponentMenu("一级菜单/二级菜单/脚本名")]
public class T2 : MonoBehaviour
{
    [MenuItem("CONTEXT/T2/一级菜单名/Function1")]
    public static void Function2() {
        Debug.Log("输出任意一句话");
    }
}

 2.EditorWindow 类

         官方文档:EditorWindow - Unity 脚本 API 

        继承了 EditorWindow类的编辑器脚本, 你可以在这个窗口中添加自定义方法,如下图演示将创建一个名为Name,有一个任意内容label的窗口

例如如下窗口

public class Window : EditorWindow
{
    [MenuItem("MyWindow/window1")]
    private static void MyWindow()
        {
        Window w =EditorWindow.GetWindow<Window>("Name");
        w.Show();

    }
    private void OnGUI() {
        GUILayout.Label("任意内容");
    }
}

3.EditorGUILayout类

        在具体绘制这一点,unity提供了一个新的类叫做EditorGUILayout,功能与GUILayout相似加入了自动布局功能

EditorGUILayout - Unity 脚本 API

        举例:每种元素都用常用api

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

public class Window : EditorWindow
{
    [MenuItem("MyWindow/window1")]
    private static void MyWindow()
        {
        Window w =EditorWindow.GetWindow<Window>("Name");
        w.Show();

    }
    //层级和标签
    int layer;
    string tag;

    //选择枚举
    enum E_AnyType{ 
        a=1,
        b=2,
        c=4,
        d=8,
        //要将枚举中的变量定义为2的幂次方,原因是多选枚举时,是按照 或运算 将得出的结果记录下来
        //比如a=1,二进制为0001,b=2,二进制为0010,或运算后结果为0011 = 3 
        //如果不按此规则,a=1,b=2,c=3,当a|b之后,得到的结果就变成了c,而不是多选a和b
    }
    E_AnyType single;
    E_AnyType multiple;

    //字符串选择对应数组值
    int returnNum;
    string[] options = { "op1", "op2", "op3", "op4" };
    int[] result = { 1,2,3,4};

    //关联资源
    GameObject obj;
    int value;//整形输入框
    
    //折叠控件
    bool isHide;
    bool isGroupHide;

    //滑动条
    float slider;
    int intSlider;
    float min;
    float max;
    private void OnGUI() {
        EditorGUILayout.LabelField("页签");
        layer =EditorGUILayout.LayerField(layer);//return int
        tag =EditorGUILayout.TagField("标签");//return sting

        single = (E_AnyType)EditorGUILayout.EnumPopup("单选枚举",single);//return typeof(E_AnyType)
        multiple = (E_AnyType)EditorGUILayout.EnumFlagsField("多选枚举",multiple);

        returnNum = EditorGUILayout.IntPopup("字符串对应数组", returnNum, options, result);
        EditorGUILayout.LabelField(returnNum.ToString());

        EditorGUILayout.DropdownButton(new GUIContent("按钮"), FocusType.Passive);//return bool

        isHide = EditorGUILayout.Foldout(isHide,"折叠控件 bool包裹内容");
        if(isHide){
          
            obj = EditorGUILayout.ObjectField("关联资源对象框", obj, typeof(GameObject), true) as GameObject;
            value = EditorGUILayout.IntField("输入框", value);
        }
        isGroupHide = EditorGUILayout.BeginFoldoutHeaderGroup(isGroupHide,"折叠组控件 必须包括开始和结束");

        EditorGUILayout.EndFoldoutHeaderGroup();

        //开关和开关组类似于折叠控件 关键词:Toggle

        slider =EditorGUILayout.Slider("滑动条",slider,0,1);
        intSlider = EditorGUILayout.IntSlider("整型滑动条",intSlider,0,1);
        //双块滑动条
        EditorGUILayout.MinMaxSlider("双块",ref min,ref max,0,1);

        EditorGUILayout.Space(10);//间隔框
        //提示框
        EditorGUILayout.HelpBox("提示框",MessageType.Warning);//MessageType选择类型

       
    }
}

4.EditorGUIUtility类

       该类是 EditorGUI 的各种辅助程序

文档EditorGUIUtility - Unity 脚本 API

public class 资源加载和工具类 : EditorWindow
{
    [MenuItem("资源加载部分/openWindow")]
    private static void OpenWindow(){
        资源加载和工具类 l = EditorWindow.GetWindow<资源加载和工具类>("资源加载与工具示例");
        l.Show();
    }

    Texture texture;
    private void OnGUI() {
        //加载Editor Default Resources 文件夹下的资源 要求有后缀名
        texture = EditorGUIUtility.Load("test.jpg") as Texture;//有判空方法 EditorGUIUtility.LoadRequired() 
        GUI.DrawTexture(new Rect(0,50,100,100),texture);//绘制

        //搜索框和选择资源
        if (EditorGUILayout.DropdownButton(new GUIContent("打开资源搜索框"), FocusType.Passive))
          EditorGUIUtility.ShowObjectPicker<Texture>(null,true,"",0);//搜索

        if(Event.current.commandName == "ObjectSelectorUpdated") {
            texture = EditorGUIUtility.GetObjectPickerObject() as Texture;//获取

            EditorGUIUtility.PingObject(texture);//高亮选中资源在Project中
           Debug.Log(texture.name);
        }

        //窗口事件传递 当SendEvent(e)执行后 会发出一个ExecuteCommand枚举类型 只需要检测这个类型 并且事件名相同即可接收
        if (EditorGUILayout.DropdownButton(new GUIContent("传递事件按钮"), FocusType.Passive))
            {
            Event e = EditorGUIUtility.CommandEvent("事件名");
            SendEvent(e);
        }
        //接收事件窗口 可以写在其他窗口之中 
        if (Event.current.type == EventType.ExecuteCommand && Event.current.commandName == "事件名") {
            Debug.Log("接收到了事件");
        }

    }
}

5.Selection类

        用于访问编辑器中的选择对象,这个类过于简单了,就不做演示,可以自行查看文档或看下面唐老师的注释

文档Selection - Unity 脚本 API

       #region 知识点一 获取当前选择的Object
       //获取当前在面板上选择的游戏物体Object
       //未选择则返回Null
       //选择多个则返回第一个选择的游戏物体
       //Selection.activeObject
       #endregion

       #region 知识点二 获取当前选择的GameObject
       //获取当前在面板上选择的游戏物体GameObject
       //未选择则返回Null
       //选择多个则返回第一个选择的游戏物体
       //Selection.activeGameObject
       #endregion

       #region 知识点三 获取当前选择的Transform
       //获取当前在面板上选择的游戏物体的Transform
       //未选择则返回Null
       //选择多个则返回第一个选择的游戏物体
       //Selection.activeTransform

       //只能获取到场景中的对象的Transform
       #endregion

       #region 知识点四 获取当前选择的所有Object
       //获取当前在面板上选择的物体数组
       //未选择则返回Null
       //Selection.objects 
       #endregion

       #region 知识点五 获取当前选择的所有GameObject
       //获取当前在面板上选择的游戏物体或Project中预设体 GameObject数组
       //未选择则返回Null
       //Selection.gameObjects
       //可以遍历获取所有信息
       #endregion

       #region 知识点六 获取当前选择的所有Transform
       //获取当前在面板上选择的游戏物体Transform数组
       //未选择则返回Null
       //Selection.transforms
       //可以遍历获取所有信息
       #endregion

   }

6.Event类

        作用:检测Unity中的事件/输入,或者是 用于UnityGUI 布局/渲染事件  

        你如果将此类写在OnGUI之中并配合EditorWindow的话那么其所有的方法与属性都将与自定义窗口有关

文档Event - Unity 脚本 API

         由于api过多且简单,故不做全部演示

  private void OnGUI() {
      //有一个大类 Event.current
      Vector2 mousePostion = Event.current.mousePosition;
      Debug.Log(mousePostion);
  }

      

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

rnn/lstm

tip&#xff1a;本人比较小白&#xff0c;看到july大佬的文章受益匪浅&#xff0c;现在其文章基础上加上自己的归纳、理解&#xff0c;以及gpt的答疑&#xff0c;如果有侵权会删。 july大佬文章来源&#xff1a;如何从RNN起步&#xff0c;一步一步通俗理解LSTM_rnn lstm-CSDN博…

【Docker大揭秘】

Docker 调试一天的血与泪的教训&#xff1a;设备条件&#xff1a;对应的build preparation相应的报错以及修改 作为记录 构建FASTLIO2启动docker获取镜像列出镜像运行containerdocker中实现宿主机与container中的文件互传 调试一天的血与泪的教训&#xff1a; 在DOCKER中跑通F…

APISQL企业版离线部署教程

针对政务、国企、医院、军工等内网物理隔离的客户&#xff0c;有时需要多次摆渡才能到达要安装软件的服务器。本教程将指导您使用Linux和Docker Compose编排服务&#xff0c;实现APISQL的离线部署。 准备 准备一台Linux(x86_64)服务器。 安装Docker Engine&#xff08;推荐版本…

音视频入门基础:AAC专题(11)——AudioSpecificConfig简介

音视频入门基础&#xff1a;AAC专题系列文章&#xff1a; 音视频入门基础&#xff1a;AAC专题&#xff08;1&#xff09;——AAC官方文档下载 音视频入门基础&#xff1a;AAC专题&#xff08;2&#xff09;——使用FFmpeg命令生成AAC裸流文件 音视频入门基础&#xff1a;AAC…

docker 可用镜像服务地址(2024.10.25亲测可用)

1.错误 Error response from daemon: Get “https://registry-1.docker.io/v2/” 原因&#xff1a;镜像服务器地址不可用。 2.可用地址 编辑daemon.json&#xff1a; vi /etc/docker/daemon.json内容修改如下&#xff1a; {"registry-mirrors": ["https://…

【AI应用落地实战】智能文档处理本地部署——可视化文档解析前端TextIn ParseX实践

湘江之畔&#xff0c;秋风送爽。前不久&#xff0c;2024长沙中国1024程序员节在长沙盛大举行。今年的程序员节主题为“智能应用新生态”&#xff0c;以科技为纽带&#xff0c;搭建起了一个共筑智能应用新生态的交流平台&#xff0c;众多技术大咖齐聚一堂&#xff0c;探讨智能应…

echarts实现 水库高程模拟图表

需求背景解决思路解决效果index.vue 需求背景 需要做一个水库高程模拟的图表&#xff0c;x轴是水平距离&#xff0c;y轴是高程&#xff0c;需要模拟改水库的形状 echarts 图表集链接 解决思路 配合ui切图&#xff0c;模拟水库形状 解决效果 index.vue <!--/*** author:…

Kubeadm搭建k8s

一、架构 节点名称规格IP地址安装组件master012C/4G&#xff0c;cpu核心数要求大于2192.168.88.76docker、kubeadm、kubelet、kubectl、flannelnode012C/2G192.168.88.20docker、kubeadm、kubelet、kubectl、flannelnode022C/2G192.168.88.21docker、kubeadm、kubelet、kubect…

transformers和bert实现微博情感分类模型提升

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【LSTM模型实现光伏发电功率的预测】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模…

【Apache Zookeeper】

一、简介 1、场景 如何让⼀个应⽤中多个独⽴的程序协同⼯作是⼀件⾮常困难的事情。开发这样的应⽤&#xff0c;很容易让很多开发⼈员陷⼊如何使多个程序协同⼯作的逻辑中&#xff0c;最后导致没有时间更好地思考和实现他们⾃⼰的应⽤程序逻辑&#xff1b;又或者开发⼈员对协同…

了解lwip

lwIP是一个小型的开源的TCP/IP协议栈&#xff08;精简版的TCP/IP协议&#xff09;&#xff0c;博客借用了其他博客的内容在此声明。 TCP/IP协议栈结构 应用层&#xff1a;HTTP,MQTT,NTP、FTP....... 传输层:TCP协议&#xff08;用于不可靠设备可靠传输&#xff09;&#xff…

基于Springboot+微信小程序的房产交易租赁服务平台设计与实现 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 该系统…

《Linux运维总结:基于ARM64+X86_64架构CPU使用docker-compose一键离线部署redis 6.2.14容器版哨兵集群》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面向不通的客户安装我们的业务系统&…

【计算机网络 - 基础问题】每日 3 题(五十九)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞…

Dolphins 简介——一种新颖的多模态语言模型

背景问题 现在的自动驾驶系统在处理复杂的多变的现实驾驶场景时&#xff0c;往往缺乏人类驾驶员的全面理解&#xff0c;及时学习和适应能力以及错误纠正能力&#xff0c;为了实现能够像人类一样理解和响应复杂现实世界场景的完全自主车辆(AV)一直是一个重要目标。Dolphins 是一…

LabVIEW汽车状态监测系统

LabVIEW汽车状态监测系统通过模拟车辆运行状态&#xff0c;有效地辅助工程师进行故障预测和维护计划优化&#xff0c;从而提高汽车的可靠性和安全性。 项目背景&#xff1a; 现代汽车工业面临着日益增长的安全要求和客户对于车辆性能的高期望。汽车状态监测系统旨在实时监控汽…

面试经典 150 题.P26. 删除有序数组中的重复项(003)

本题来自&#xff1a;力扣-面试经典 150 题 面试经典 150 题 - 学习计划 - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台https://leetcode.cn/studyplan/top-interview-150/ 题解&#xff1a; class Solution {public int removeDuplicates(int[] nums) …

FPGA时序分析和约束学习笔记(3、Timequest时序路径详解和优化)

FPGA时序分析和约束学习笔记&#xff08;3、Timequest时序路径详解和优化&#xff09; Timequest中Data Path分析 Data Arrival Path clock path&#xff1a;时钟信号到达源寄存器时钟端口的时间 data path&#xff1a;数据从源寄存器Q端口出发到达目标寄存器D端口的时间 D…

浮动+flex布局

一.浮动 1.介绍 2.效果 <style> .one{ width: 100px; height: 100px; background-color: red; float: left; } .two{ width: 200px; height: 200px; background-color: blue; float: right; } </style> </head> <body> <div class"one&quo…

yandex企业邮箱:烽火域名邮箱有哪些优势?

yandex企业邮箱申请教程&#xff1f;如何用yandex免费域名邮箱&#xff1f; yandex企业邮箱作为一款备受推崇的企业邮箱服务&#xff0c;凭借其独特的优势&#xff0c;成为了众多企业的首选。烽火将深入探讨yandex企业邮箱的优势&#xff0c;特别是与烽火域名邮箱相比&#xf…