目录

Unity透视相机下屏幕坐标转世界坐标

目录

Unity透视相机下屏幕坐标转世界坐标

效果:将输入的鼠标坐标点击的物体位置转换为世界坐标

代码如下:


Vector3 transpos = ScreenToWorldPlanePos(Input.mousePosition);
public Vector3 ScreenToWorldPlanePos(Vector3 screenPosition)
    {
        Debug.Log("pos"+Camera.main.ScreenToWorldPoint(screenPosition));
        Vector3 targetScreenPos=Camera.main.WorldToScreenPoint(CurrentObject.transform.position);
//currentObject就是被鼠标射线点击到的物体,怎么获取到的这就不赘述了
        float depth=targetScreenPos.z;
        screenPosition.z=depth;
        Vector3 worldPosition = Camera.main.ScreenToWorldPoint(screenPosition);
    

        return worldPosition;

    }

应该会有人疑问为什么不就用Camera.main.ScreenToWorldPoint(screenPosition)这个函数吧? 因为我之前很疑问

因为这里有个很大的坑是,用这个方法转出来的屏幕坐标的 深度值(也就是z值)是相机近平面的值 !!!

https://i-blog.csdnimg.cn/direct/43487b851a0a4d7683306b6d028b384e.png

https://i-blog.csdnimg.cn/direct/99ae9e542d864a84b01fce50fe3080c9.png

所以,要想得到正确的z值,需要获取被点击物体在屏幕空间本来的z值,也就是将被点击物体的世界坐标转换为屏幕坐标,再将转换得到的屏幕坐标的z值赋给鼠标传入的屏幕空间坐标

PS.屏幕坐标本身不是二维坐标的意思哦,不要被它的名字骗了,它依旧是三维坐标,只是是屏幕空间的坐标系,需要转换为世界空间下的坐标系

https://i-blog.csdnimg.cn/direct/db4a7090da0a43f2b8ec652b78577315.png

又有人要问了,为什么不能直接把鼠标坐标转换成世界坐标后把当前物体的z值赋给它,就像这样

Vector3 worldPosition = Camera.main.ScreenToWorldPoint(screenPosition);
worldPosition.z = CurrentObject.transform.position.z;

因为世界空间下的z值含义和屏幕空间下的z值(摄像机到目标点的深度)含义不一样,并不能让我们达成使鼠标点击点与被击物体处于相机视角同一深度的目的 https://i-blog.csdnimg.cn/direct/37a5e10c73d549cb8a01520fe797926f.png

左手系:z轴朝前,y轴向上

右手系:-z轴朝前,y轴向上

用手比一下就知道啦