Unity编辑器拓展——Editor模式下屏幕坐标转换为世界坐标

发会牢骚,最近一直在做Unity的编辑器拓展,其中难的地方不少,但不至于到看不懂的地步,可一做到关于坐标转换的内容时把我弄不会了。

这个不查不知道,一查吓一跳,Unity的坐标系非常多,有世界坐标,屏幕坐标,局部坐标,视窗坐标等等,而且每一个都是不一样的坐标系,所以关于Unity的坐标变换都挺麻烦的,但其实也不是难题,有很多现成的答案,前提是不在Editor模式下操作。

淦就淦在我就是要做编辑器拓展,所以就遇到了几乎一片空白的领域。不是没有相关的文章,关于编辑器拓展下的坐标系转换是有文章的,但在我的情况下全都不对,我就纳闷了,甚至想要直接写函数去实现,不过在磨了一天一夜后在机缘巧合下给我看出了问题。


目录

描述问题

问题所在

解决办法


描述问题

我做的是2D游戏,在编辑模式下的一个拓展窗口内需要为一个数据选定场景坐标,我首先想到的是通过鼠标位置转换成世界坐标来实现。有各种各样的问题,不过大都可以在百度上找到答案,只是关键的坐标转换却出了问题,我死活都拿不到想要的数据。

问题所在

(随便找的图)

P1:我需要转换的P2物体内的坐标位置,即鼠标点击的位置

P2:某物体的位置点

P3:场景窗口的左上角的位置

P4:场景窗口的左下角的位置

获取P1坐标的代码如下

    private void OnSceneView(SceneView sceneView)
    {
        //鼠标左键点击判断
        if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
        {
                Vector2 newPosition;

                //P2指P1所需要转换的位置的父物体
                Transform P2 = GameObject.Find("P2").transform;     
                
                //坐标转换
                RectTransformUtility.ScreenPointToLocalPointInRectangle(P2.GetComponent<RectTransform>(), GetMousePos(), sceneView.camera, out newPosition);
                
                Debug.Log(newPosition);
            }
        }
    }

Input类没法在编辑模式下用,所以用场景事件类,而RectTransformUtility.ScreenPointToLocalPointInRectangle这个方法就不多介绍了,简单来说就将屏幕坐标转换为某个物体内的坐标,挺人性的,就是没摸透时用有点折磨。RectTransformUtility类还有其他转换方法,百度上挺多答案的。

一开始我用Event.current.mousePosition来获取鼠标位置,我想将P1从屏幕坐标转换为世界坐标,用的是Camera自带的转换函数,是错的。因为P1的坐标不是正确的数据,不是准确的屏幕坐标。

常用的坐标系有这几个

而P1的坐标是GUI坐标系的,不能直接拿来转换。Event.current.mousePosition获取的鼠标坐标是GUI坐标,需要先将其转换为Screen的坐标系,转换为屏幕坐标才能用。

也就是P3是GUI坐标系的原点,而P4是屏幕坐标系的原点,P1在P3的坐标系下,P2在世界坐标系下,总之在这乱成一锅粥的坐标系下进行转换。

解决办法

    public static Vector3 GetMousePos()
    {
        SceneView sceneView = SceneView.currentDrawingSceneView;

        //当前屏幕坐标,左上角(0,0)右下角(camera.pixelWidth,camera.pixelHeight)
        Vector2 mousePos = Event.current.mousePosition;

        //retina 屏幕需要拉伸值
        float mult = 1;

#if UNITY_5_4_OR_NEWER
        mult = EditorGUIUtility.pixelsPerPoint;

#endif
        //转换成摄像机可接受的屏幕坐标,左下角是(0,0,0);右上角是
        (camera.pixelWidth,camera.pixelHeight,0)
        mousePos.y = sceneView.camera.pixelHeight - mousePos.y * mult;
        mousePos.x *= mult;

        //近平面往里一些,才能看到摄像机里的位置
        Vector3 fakePoint = mousePos;
        fakePoint.z = 10;
        return fakePoint;
    }

这个函数返回的就是准确的屏幕坐标,将GUI坐标系的坐标转换为Screen坐标系下的,我是直接拿网上的代码改了一下,因为是2D项目,所以应该和Z轴没关系,当然也不能设置在相机背面,这点就不说了。

上面的代码出处:Unity获取Scene窗口下的鼠标位置的世界坐标_BRK小布的博客-CSDN博客_unity 获取窗口位置

源码直接转成世界坐标,我想用Camera的转换函数也行,看情况吧,源码没法转换成某个物体内的坐标系。

总结

淦他娘的Unity,坐标转换弄死人了,不过弄懂了这块内容基本上以后遇到类似问题就大致有数了。

首先弄清楚获取的坐标到底是在哪个坐标系下的,然后再转换到对应的坐标系就行了。对了,有部分原因是因为用的Camera弄错了,我的项目里有两个Camera,但都是错的,这其实也应该是一个坑,而且还没搞懂,弄了好久,测这测那的,最后是换成了sceneView.camera才拿到了正确的数据,难道还有隐藏的摄像机,不太清楚,如果是用的OnSceneView(SceneView sceneView)事件函数,直接用sceneView.camera这个摄像机就行了,大概(⊙_⊙)。

最后,能帮到你就大概达到了写这个文章的目的,祝各位好运。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Unity编辑器扩展是指通过自定义脚本来扩展Unity编辑器的功能和界面。在Unity中,可以使用编辑器扩展来创建自定义的面板、工具栏、菜单项等,以便更好地支持开发者的工作流程和需求。 在编辑器扩展中,有几个重要的类需要了解。首先是Editor类,它是所有自定义编辑器的基类,通过继承Editor类可以创建自定义的Inspector面板,用于编辑特定组件的属性。其次是EditorWindow类,它是创建自定义窗口的基类,可以用于创建独立的编辑器工具窗口。然后是EditorGUI和EditorGUILayout类,它们用于在自定义面板中创建UI元素,如按钮、文本框、滑动条等。这两个类的区别在于EditorGUI需要手动计算UI元素的位置和大小,而EditorGUILayout会自动进行排版和计算坐标。此外,还有一些其他常用的类,如GUI、GUILayout、EditorGUIUtility、EditorUtility、AssetDatabase、SceneView和Handles等,它们提供了各种用于编辑器扩展的功能和工具。 使用编辑器扩展可以提高开发效率,使开发者能够更方便地进行编辑器自定义和工作流程优化。通过自定义面板和工具,可以根据项目需求添加额外的功能和工具,提供更好的用户体验和开发环境。同时,编辑器扩展也为开发者提供了更多的自由度和创造力,可以根据自己的需求进行定制和扩展。 总结起来,Unity编辑器扩展是通过自定义脚本来扩展Unity编辑器的功能和界面,可以创建自定义的面板、工具栏、菜单项等,提供更好的开发环境和用户体验。常用的类包括EditorEditorWindow、EditorGUI、EditorGUILayout、GUI、GUILayout、EditorGUIUtility、EditorUtility、AssetDatabase、SceneView和Handles等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三青云烟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值