【Unity】 UI跟随3D物体,世界坐标转UI坐标

1.世界坐标转屏幕坐标,再转换UI坐标

RectTransformUtility.ScreenPointToWorldPointInRectangle将一个屏幕空间点转换为 RectTransform 的本地空间中位于其矩形平面上的一个位置。

ScreenPointToWorldPointInRectangle的RectTransform参数,最好使用此UI的Canvas。这样计算的ui坐标z轴比较稳定。

cam 参数应为与此屏幕点关联的摄像机。对于设置为 Screen Space - Overlay 模式的 Canvas 中的 RectTransform,cam 参数应为 null。

//此方法的摄像机用可以看到物体的摄像机。
Vector2 screenPos = Camera.main.WorldToScreenPoint(targetObj.transform.position); 
//此方法的摄像机用UI摄像机,。
RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, screenPos, Camera.main,out Vector3 outPos);
rt.position = outPos;

注意:由于基于摄像机进行了两次运算,此方法计算的结果,由于精度问题,会有一点偏差,导致ui抖动。

如写在Update或LateUpdate中,可能会随Camera移动,产生大幅抖动。卸载FixedUpdate会抖动小一些。因此我是用了第二种方法。

2.世界坐标转屏幕坐标,将屏幕坐标计算为UI的localPosition

首先还是世界坐标转换为屏幕坐标

//此方法的摄像机用可以看到物体的摄像机。
Vector2 screenPos = Camera.main.WorldToScreenPoint(targetObj.transform.position); 

屏幕坐标的原点(0,0)在左下角,右上角为(Screen.width,Screen.heigth)

UI坐标的原点(0,0)在正中心,所以我们要减去偏移量(Screen.width / 2, Screen.heigth / 2)。

考虑到UI的层级关系,需减去父物体的localPosition。

    	  screenPos.x -= Screen.width / 2;
            screenPos.y -= Screen.height / 2;
            while (rt.parent != null && rt.parent.GetComponent<Canvas>() == null)
            {
                screenPos -= rt.parent.localPosition;
                rt = rt.parent;
            }

再将最后得到的坐标赋值给ui。

完整代码

	//此方法的摄像机用可以看到物体的摄像机。
	Vector2 screenPos = Camera.main.WorldToScreenPoint(targetObj.transform.position); 
    screenPos.x -= Screen.width / 2;
    screenPos.y -= Screen.height / 2;
	while (rt.parent != null && rt.parent.GetComponent<Canvas>() == null)
    {
            screenPos -= rt.parent.localPosition;
            rt = rt.parent;
    }
    rt.position = outPos;

此方式不会造成UI抖动。

猜你喜欢

转载自blog.csdn.net/boyZhenGui/article/details/125913553