16.EditorGUIUtility窗口事件坐标转换

16.EditorGUIUtility-窗口事件传递坐标转换


16.1 知识点

窗口事件传递

在某窗口发送事件
Event e = EditorGUIUtility.CommandEvent(“事件名”);
获取到另一个窗口win后,让该窗口调用win.SendEvent(e)

在另一个窗口中可以通过以下代码接受事件
Event.current.type == EventType.ExecuteCommand 判断 是否有事件执行
Event.current.commandName == “事件名”判断 执行的是哪个事件

在传递事件时 会自动将接受事件的窗口打开 不管对象是否有监听处理对应的内容 同时焦点也会移到接事件的窗口

public class MyEditorGUIUtilityLearnWindow : EditorWindow
{
    private void OnGUI()
    {
        //窗口事件传递
        if(GUILayout.Button("传递事件"))
        {
            //声明事件
            Event e = EditorGUIUtility.CommandEvent("韬老狮的事件");
            MyEditorGUILearnWindow win = EditorWindow.GetWindow<MyEditorGUILearnWindow>();
            win.SendEvent(e);
        }
    }
}

public class MyEditorGUILearnWindow : EditorWindow
{
    private void OnGUI()
    {
        if(Event.current.type == EventType.ExecuteCommand)
        {
            if(Event.current.commandName == "韬老狮的事件")
            {
                Debug.Log("收到韬老狮的事件");
            }
        }
    }
}

坐标转换

屏幕坐标系:原点为屏幕左上角
GUI坐标系:原点为当前窗口左上角

GUIToScreenPoint:将点从GUI位置转换为屏幕空间
GUIToScreenRect:将rect从GUI位置转换为屏幕空间

ScreenToGUIPoint:将点从屏幕空间转换为GUI位置
ScreenToGUIRect:将rect从屏幕空间转换为GUI位置

// 坐标转换测试按钮
if (GUILayout.Button("坐标转换测试"))
{
    // 创建一个Vector2对象,表示GUI坐标
    Vector2 v = new Vector2(10, 10);

    // 将GUI坐标转换为屏幕坐标
    Vector2 screenPos = EditorGUIUtility.GUIToScreenPoint(v);

    // 在GUI中创建一个矩形区域
    GUI.BeginGroup(new Rect(10, 10, 100, 100));

    // 在布局内部进行坐标转换
    // 注意:如果包裹在布局相关函数中,位置需要加上布局的偏移再进行转换
    Vector2 screenPos2 = EditorGUIUtility.GUIToScreenPoint(v);

    // 结束矩形区域
    GUI.EndGroup();

    // 打印坐标信息
    Debug.Log("GUI:" + v + " Screen:" + screenPos + " 布局内坐标:" + screenPos2);
}

多显示器也会参与计算


16.2 知识点代码

Lesson16_EditorGUIUtility_窗口事件传递坐标转换

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

public class Lesson16_EditorGUIUtility_窗口事件传递坐标转换 : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 窗口事件传递

        // 在某窗口发送事件
        //  Event e = EditorGUIUtility.CommandEvent("事件名");
        //  获取到另一个窗口后,让该窗口调用SendEvent(e) 
        
        //  在另一个窗口中可以通过一下代码接受事件
        //  Event.current.type == EventType.ExecuteCommand 判断
        //  Event.current.commandName == "事件名"判断

        //在传递事件时 会自动将接受事件的窗口打开 不管对象是否有监听处理对应的内容 同时焦点也会移到接事件的窗口

        #endregion

        #region 知识点二 坐标转换

        //  屏幕坐标系:原点为屏幕左上角
        //  GUI坐标系:原点为当前窗口左上角

        //  GUIToScreenPoint:将点从GUI位置转换为屏幕空间
        //  GUIToScreenRect:将rect从GUI位置转换为屏幕空间

        //  ScreenToGUIPoint:将点从屏幕空间转换为GUI位置
        //  ScreenToGUIRect:将rect从屏幕空间转换为GUI位置

        #endregion
    }
}

MyEditorGUIUtilityLearnWindow

using System;
using UnityEditor;
using UnityEngine;

public class MyEditorGUIUtilityLearnWindow : EditorWindow
{
    [MenuItem("编辑器拓展教程/MyEditorGUIUtilityLearnWindow")]
    private static void OpenMyEditorGUIUtilityLearnWindow()
    {
        MyEditorGUIUtilityLearnWindow win =
            EditorWindow.GetWindow<MyEditorGUIUtilityLearnWindow>("EditorGUIUtility学习面板");
        //win.titleContent = new GUIContent("EditorGUIUtility学习面板");
        win.Show();
    }

    #region Lesson14_EditorGUIUtility_资源加载

    private Texture img;
    private Texture img2;

    #endregion

    #region Lesson15_EditorGUIUtility_搜索框查询对象选中提示

    private Texture img3;

    #endregion

    private void OnGUI()
    {
        #region Lesson14_EditorGUIUtility_资源加载

        //加载资源(如果资源不存在返回null)
        if (GUILayout.Button("加载编辑器图片资源"))
            img = EditorGUIUtility.Load("head.png") as Texture;
        if (img != null)
            GUI.DrawTexture(new Rect(0, 50, 160, 90), img);

        //加载资源(如果资源不存在会直接报错)
        if (GUILayout.Button("加载编辑器图片资源(如果资源不存在会直接报错)"))
            img2 = EditorGUIUtility.LoadRequired("head.png") as Texture;
        if (img2 != null)
            GUI.DrawTexture(new Rect(0, 150, 160, 90), img2);

        #endregion

        #region Lesson15_EditorGUIUtility_搜索框查询对象选中提示

        //搜索框查询
        if (GUILayout.Button("打开搜索框查询窗口"))
        {
            EditorGUIUtility.ShowObjectPicker<Texture>(null, true, "head", 0);
        }

        if (Event.current.commandName == "ObjectSelectorUpdated")
        {
            img3 = EditorGUIUtility.GetObjectPickerObject() as Texture;
            if (img3 != null)
                Debug.Log(img3.name);
        }
        else if (Event.current.commandName == "ObjectSelectorClosed")
        {
            img3 = EditorGUIUtility.GetObjectPickerObject() as Texture;
            if (img3 != null)
                Debug.Log("窗口关闭 - " + img3.name);
        }


        //对象选中提示提示
        if (GUILayout.Button("高亮选中对象"))
        {
            if (img3 != null)
                EditorGUIUtility.PingObject(img3);
        }

        #endregion

        #region Lesson16_EditorGUIUtility_窗口事件传递坐标转换

        //窗口事件传递
        if (GUILayout.Button("传递事件"))
        {
            //声明事件
            Event e = EditorGUIUtility.CommandEvent("韬老狮的事件");
            MyEditorGUILearnWindow win = EditorWindow.GetWindow<MyEditorGUILearnWindow>();
            win.SendEvent(e);
        }

        //坐标转换
        if (GUILayout.Button("坐标转换测试"))
        {
            Vector2 v = new Vector2(10, 10);

            Vector2 screenPos = EditorGUIUtility.GUIToScreenPoint(v);

            GUI.BeginGroup(new Rect(10, 10, 100, 100));
            //转换函数 如果包裹在布局相关函数中 那么位置要加上布局的偏移 再进行转换
            Vector2 screenPos2 = EditorGUIUtility.GUIToScreenPoint(v);
            GUI.EndGroup();

            Debug.Log("GUI:" + v + "Screen:" + screenPos + "布局内坐标:" + screenPos2);
        }

        #endregion
    }
}

MyEditorGUILearnWindow

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


public enum E_TestType
{
    One = 1,
    Two = 2,
    Three = 4,
    One_and_Two = 1 | 2,
}

public class MyEditorGUILearnWindow : EditorWindow
{
    [MenuItem("编辑器拓展教程/MyEditorGUILearnWindow")]
    private static void OpenMyEditorGUILearnWindow()
    {
        MyEditorGUILearnWindow win = EditorWindow.GetWindow<MyEditorGUILearnWindow>("EditorGUI知识讲解窗口");
        //win.titleContent = new GUIContent("EditorGUI知识讲解窗口");
        win.Show();
    }

    #region Lesson05_EditorGUI_文本层级标签颜色

    int layer;
    string tag;
    Color color;

    #endregion

    #region Lesson06_EditorGUI_枚举整数选择按下按钮

    E_TestType type;
    E_TestType type2;

    string[] strs = { "选择123", "选择234", "选择345" };
    int[] ints = { 123, 234, 345 };
    int num = 0;

    #endregion

    #region Lesson07_EditorGUI_对象关联各类型输入

    GameObject gameObj;


    int i;
    int i2;
    float f;
    double d;
    long l;

    string str;
    Vector2 vec2;
    Vector3 vec3;
    Vector4 vec4;

    Rect rect;
    Bounds bounds;
    BoundsInt boundsInt;

    #endregion

    #region Lesson08_EditorGUI_折叠折叠组

    bool isHide;
    bool isHideGroup;

    #endregion

    #region Lesson09_EditorGUI_开关开关组

    bool isTog;
    bool isTogLeft;
    bool isTogGroup;

    #endregion

    #region Lesson10_EditorGUI_滑动条双滑块滑动条

    float fSlider;
    int iSlider;
    float leftV;
    float rightV;

    #endregion

    #region Lesson12_EditorGUI_动画曲线布局

    AnimationCurve curve = new AnimationCurve();

    Vector2 vec2Pos;

    #endregion

    private void OnGUI()
    {
        //窗口中的控件相关绘制 逻辑处理相关的内容
        //EditorGUI相关的控件 同样还是需要在OnGUI当中进行实现 才能被显示出来

        #region Lesson05_EditorGUI_文本层级标签颜色

        if (isHide)
        {
            //文本控件
            EditorGUILayout.LabelField("文本标题", "测试内容");
            EditorGUILayout.LabelField("文本内容");

            //层级标签控件
            // layer = EditorGUILayout.LayerField(layer);//这样可能别人看不明白是选择什么的。建议加个字符串提示
            layer = EditorGUILayout.LayerField("层级选择", layer);
            // tag = EditorGUILayout.TagField(tag);//这样可能别人看不明白是选择什么的。建议加个字符串提示
            tag = EditorGUILayout.TagField("标签选择", tag);

            //颜色获取控件
            color = EditorGUILayout.ColorField(new GUIContent("自定义颜色获取"),
                color, true, true, true);
        }

        #endregion

        #region Lesson06_EditorGUI_枚举整数选择按下按钮

        //枚举选择
        type = (E_TestType)EditorGUILayout.EnumPopup("枚举选择", type);

        type2 = (E_TestType)EditorGUILayout.EnumFlagsField("枚举多选", type2);

        //整数选择控件
        //返回值 其实是整数数组当中的某一个值
        num = EditorGUILayout.IntPopup("整数单选框", num, strs, ints);
        EditorGUILayout.LabelField(num.ToString()); //显示返回的值是什么

        //按下就响应的按钮
        if (EditorGUILayout.DropdownButton(new GUIContent("按钮上文字"), FocusType.Passive))
            Debug.Log("按下就响应");

        #endregion

        #region Lesson07_EditorGUI_对象关联各类型输入

        if (isHide)
        {
            //对象关联
            gameObj = EditorGUILayout.ObjectField("关联资源对象", gameObj, typeof(GameObject), false) as GameObject;


            //各类型输入
            i = EditorGUILayout.IntField("Int输入框", i);
            EditorGUILayout.LabelField(i.ToString());
            l = EditorGUILayout.LongField("long输入框", l);
            f = EditorGUILayout.FloatField("Float 输入:", f);
            d = EditorGUILayout.DoubleField("double 输入:", d);

            str = EditorGUILayout.TextField("Text输入:", str);
            vec2 = EditorGUILayout.Vector2Field("Vec2输入: ", vec2);
            vec3 = EditorGUILayout.Vector3Field("Vec3输入: ", vec3);
            vec4 = EditorGUILayout.Vector4Field("Vec4输入: ", vec4);

            rect = EditorGUILayout.RectField("rect输入: ", rect);
            bounds = EditorGUILayout.BoundsField("Bounds输入: ", bounds);
            boundsInt = EditorGUILayout.BoundsIntField("Bounds输入: ", boundsInt);

            //注意:EditorGUILayout中还有一些Delayed开头的输入控件
            //     他们和普通输入控件最主要的区别是:在用户按 Enter 键或将焦点从字段移开之前,返回值不会更改
            i2 = EditorGUILayout.DelayedIntField("Int输入框", i2);
            EditorGUILayout.LabelField(i2.ToString());
        }

        #endregion

        #region Lesson08_EditorGUI_折叠折叠组

        //折叠
        isHide = EditorGUILayout.Foldout(isHide, "折叠控件", false);
        //第二个参数为true代表点击整体都能展开收起折叠 为false只能点击前面箭头展开收起折叠

        if (isHide)
        {
            EditorGUILayout.LabelField("折叠文本内容");
        }


        //折叠组
        isHideGroup = EditorGUILayout.BeginFoldoutHeaderGroup(isHideGroup, "折叠组控件");
        //和折叠的主要区别是折叠组会高亮 且 折叠组需要结束组

        if (isHideGroup)
        {
            EditorGUILayout.LabelField("折叠组文本内容");
        }

        EditorGUILayout.EndFoldoutHeaderGroup();

        #endregion

        #region Lesson09_EditorGUI_开关开关组

        //开关组控件
        isTogGroup = EditorGUILayout.BeginToggleGroup("开关组控件", isTogGroup);


        //开关控件
        isTog = EditorGUILayout.Toggle("开关控件", isTog);
        isTogLeft = EditorGUILayout.ToggleLeft("左侧开关", isTogLeft);


        EditorGUILayout.EndToggleGroup();

        #endregion

        #region Lesson10_EditorGUI_滑动条双滑块滑动条

        //滑动条
        fSlider = EditorGUILayout.Slider("滑动条", fSlider, 0, 10);
        iSlider = EditorGUILayout.IntSlider("整形滑动条", iSlider, 0, 10);

        //双块滑动条
        EditorGUILayout.MinMaxSlider("双块滑动条", ref leftV, ref rightV, 0, 10);
        EditorGUILayout.LabelField(leftV.ToString());
        EditorGUILayout.LabelField(rightV.ToString());

        #endregion

        #region Lesson11_EditorGUI_帮助框垂直间隔

        //帮助框控件
        EditorGUILayout.HelpBox("一般提示", MessageType.None);
        //间隔控件
        EditorGUILayout.Space(10);
        EditorGUILayout.HelpBox("感叹号提示", MessageType.Info);
        EditorGUILayout.Space(50);
        EditorGUILayout.HelpBox("警告符号提示", MessageType.Warning);
        EditorGUILayout.Space(100);
        EditorGUILayout.HelpBox("错误符号提示", MessageType.Error);

        #endregion

        #region Lesson12_EditorGUI_动画曲线布局

        //动画曲线控件
        curve = EditorGUILayout.CurveField("曲线控件", curve);

        //布局API
        EditorGUILayout.BeginHorizontal(); //开始水平布局
        EditorGUILayout.LabelField("123123");
        EditorGUILayout.LabelField("123123");
        EditorGUILayout.LabelField("123123");
        EditorGUILayout.EndHorizontal(); //结束水平布局

        EditorGUILayout.BeginVertical(); //开始垂直布局
        EditorGUILayout.LabelField("456456");
        EditorGUILayout.LabelField("456456");
        EditorGUILayout.LabelField("456456");
        EditorGUILayout.EndVertical(); //结束垂直布局

        vec2Pos = EditorGUILayout.BeginScrollView(vec2Pos); //开启滚动视图
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.LabelField("789789");
        EditorGUILayout.EndScrollView(); //结束滚动视图

        #endregion

        #region Lesson16_EditorGUIUtility_窗口事件传递坐标转换

        if (Event.current.type == EventType.ExecuteCommand)
        {
            if (Event.current.commandName == "韬老狮的事件")
            {
                Debug.Log("收到韬老狮的事件");
            }
        }

        #endregion
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏