Unity世界坐标转屏幕坐标等关系——最白话,手把手教你做系列。

遇到问题

通过一个世界坐标,在屏幕对应位置生成Ui。

记录原因

在没遇到这个问题之前也听过类似的需求,想法也很简单,就是有个方法Camera.main.WorldToScreenPoint();世界坐标转屏幕坐标,然后克隆物体并赋值。
如图示方法
在这里插入图片描述然而,在实际操作的时候却发现,无论怎么操作,都无法达到所需要的效果。这就让我对自己的云代码能力产生了怀疑。
之后我通过对比输出的屏幕坐标和我需要显示的物体位置不断对比,发现我对这几种概念完全懵了。屏幕坐标?世界坐标?视口坐标?

重点

通过查询很多材料。我意识到原来Unity中有四种坐标系
1 .World Space(世界坐标):三维空间坐标,Vector3。
2.Screen Space(屏幕坐标):以像素来定义的,以屏幕的左下角为(0,0)点,右上角为(Screen.width,Screen.height),Z的位置是以相机的世界单位来衡量的。
3.ViewPort Space(视口坐标):视口坐标是标准的和相对于相机的。相机的左下角为(0,0)点,右上角为(1,1)点,Z的位置是以相机的世界单位来衡量的。
4.UGUI界面的坐标系:与锚点有关,锚点所在位置即为(0,0)。
那么问题就出来了。
我们的需求是通过一个世界坐标,在屏幕对应位置生成Ui。所以我主观的认为这个屏幕对应位置即为屏幕坐标。然而事实上在3D的场景中屏幕显示的位置就是物体所在的位置。那么,这个屏幕的对应位置应该Ui的坐标。所以需求其实应该是通过一个世界坐标,在Ui的对应位置上生成一个Ui。
那么问题就好解决了。以下是我用到的方法作为参考,参数都有说明。

/// <summary>
    /// 世界坐标转屏幕坐标
    /// </summary>
    /// <param name="pos"></param>
    public void WorldToScreen(Vector3 pos)
    {
        //克隆物体
        GameObject obj = Instantiate(Resources.Load("prefabs/Wts_Icon")) as GameObject; 
        //获取屏幕坐标
        Vector3 pt = Camera.main.WorldToScreenPoint(Cube.transform.position);
        //获取在(参数1)Canvas下(参数2)屏幕坐标对应(参数3)摄像机下的(参数3)Ui坐标
        Vector2 v;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(m_canvas.transform as RectTransform, pt, m_cam, out v);     
        //给物体位置赋值并设置父物体
        obj.transform.position = v;
        obj.transform.SetParent(m_canvas.transform, false);     
    }

这种也是做血条跟随之类需求的实现方式之一。
最后点一下obj.transform.SetParent(m_canvas.transform, false);这个方法不能用obj.transform.SetParent(m_canvas.transform);代替,也不能随意改动执行顺序,也是坑之一。因为你生成的物体是在3D场景里,直接放在父物体下会发生位置和大小的变化,改动顺序也是一样。

以上。

发布了27 篇原创文章 · 获赞 26 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_39860954/article/details/102614079