Extensão Unity Editor - Converta coordenadas da tela em coordenadas mundiais no modo Editor

Vou reclamar. Tenho trabalhado na expansão do editor do Unity recentemente. Há muitas dificuldades nisso, mas não chega ao ponto em que eu não consiga entender. Mas quando se trata de conversão coordenada, eu não consigo descobrir.

Não sei disso a menos que verifique, mas ficarei surpreso quando verificar. O Unity tem muitos sistemas de coordenadas, incluindo coordenadas mundiais, coordenadas de tela, coordenadas locais, coordenadas de janela, etc., e cada um é diferente. sistema de coordenadas, portanto, sobre as coordenadas da Transformação da Unidade é bastante problemático, mas na verdade não é um problema.Existem muitas respostas prontas, desde que não seja operado no modo Editor.

O problema é que eu só quero fazer a expansão do editor, então encontrei um campo quase em branco. Não é que não existam artigos relevantes. Existem artigos sobre conversão de sistema de coordenadas na expansão do editor, mas no meu caso eles estavam todos errados. Fiquei confuso e até queria escrever uma função diretamente para implementá-la. No entanto, depois de trabalhar por um dia e noite, vi o problema por acaso.


Índice

Descreva o problema

problema reside em

Solução


Descreva o problema

Estou fazendo um jogo 2D. Em uma janela expandida no modo de edição, preciso selecionar as coordenadas da cena para um dado. A primeira coisa que pensei foi converter a posição do mouse em coordenadas mundiais. Existem várias perguntas, mas a maioria delas pode ser respondida no Baidu.No entanto, há um problema com a conversão das coordenadas principais e não consigo obter os dados que desejo.

problema reside em

(Fotos que encontrei aleatoriamente)

P1: A posição da coordenada dentro do objeto P2 que preciso converter, ou seja, a posição do clique do mouse

P2: O ponto de posição de um objeto

P3: A posição do canto superior esquerdo da janela da cena

P4: A posição do canto inferior esquerdo da janela da cena

O código para obter as coordenadas de P1 é o seguinte

    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);
            }
        }
    }

A classe Input não pode ser usada no modo de edição, então a classe de evento de cena é usada. O método RectTransformUtility.ScreenPointToLocalPointInRectangle não será apresentado em detalhes. Simplesmente falando, ele converte as coordenadas da tela nas coordenadas dentro de um objeto. É bastante humano, mas não é. É um pouco torturante usar quando você sente isso. A classe RectTransformUtility possui outros métodos de conversão e há algumas respostas no Baidu.

No início, usei Event.current.mousePosition para obter a posição do mouse. Queria converter P1 das coordenadas da tela para coordenadas do mundo. Usei a função de conversão que vem com a Câmera, o que está errado. Porque as coordenadas de P1 não são dados corretos, nem coordenadas de tela precisas.

Os sistemas de coordenadas comumente usados ​​incluem estes

As coordenadas de P1 estão no sistema de coordenadas GUI e não podem ser convertidas diretamente. As coordenadas do mouse obtidas por Event.current.mousePosition são coordenadas GUI. Elas precisam ser convertidas para o sistema de coordenadas da Tela antes de serem usadas.

Ou seja, P3 é a origem do sistema de coordenadas GUI e P4 é a origem do sistema de coordenadas da tela. P1 está no sistema de coordenadas de P3 e P2 está no sistema de coordenadas mundial. Resumindo, a transformação é realizado neste sistema de coordenadas confuso.

Solução

    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;
    }

O que esta função retorna são as coordenadas precisas da tela, convertendo as coordenadas do sistema de coordenadas da GUI no sistema de coordenadas da tela. Peguei o código diretamente da Internet e o alterei. Por ser um projeto 2D, não deve ter nada a ver com o eixo Z, e claro que não pode. Ele está colocado na parte traseira da câmera, então não vou falar sobre isso.

Fonte do código acima: Unity obtém as coordenadas mundiais da posição do mouse sob a janela da cena_BRK Blog-CSDN de Xiaobu blog_unity obtém a posição da janela

O código-fonte pode ser convertido diretamente em coordenadas mundiais. Acho que também é possível usar a função de conversão da Câmera. Depende da situação. O código-fonte não pode ser convertido em um sistema de coordenadas dentro de um objeto.

Resumir

Maldito Unity, a conversão coordenada está matando pessoas, mas depois de entender esse conteúdo, você basicamente poderá encontrar problemas semelhantes no futuro.

Primeiro descubra em qual sistema de coordenadas estão as coordenadas obtidas e depois converta para o sistema de coordenadas correspondente. A propósito, parte do motivo é porque usei a câmera errada. Há duas câmeras no meu projeto, mas ambas estão erradas. Na verdade, isso deveria ser uma armadilha e ainda não entendi. Levei um tempo muito tempo para testar isso. Depois de testar isso, finalmente mudei para sceneView.camera para obter os dados corretos. Existe uma câmera escondida? Não tenho certeza. Se você usar a função de evento OnSceneView (SceneView sceneView), basta usar o câmera sceneView.camera diretamente. Sim, provavelmente (⊙_⊙).

Por fim, se puder ajudá-los, provavelmente alcancei o objetivo de escrever este artigo. Desejo a todos boa sorte.

Acho que você gosta

Origin blog.csdn.net/weixin_49779414/article/details/127380072
Recomendado
Clasificación