我在画布中有一个带有屏幕空间的图像用户界面 - 相机渲染模式。我喜欢做的是通过循环遍历所有LineRenderer
位置并更改其y轴,将LineRenderer
移动到图像垂直位置。我的问题是我无法获得LineRenderer
可以理解的图像的正确位置。我已尝试使用ViewportToWorldPoint
和ScreenToWorldPoint
,但其位置不同。
Vector3 val = Camera.main.ViewportToWorldPoint(new Vector3(image.transform.position.x, image.transform.position.y, Camera.main.nearClipPlane));
for (int i = 0; i < newListOfPoints.Count; i++)
{
line.SetPosition(i, new Vector3(newListOfPoints[i].x, val.y, newListOfPoints[i].z));
}
使用Vector3 val = Camera.main.ScreenToWorldPoint(new Vector3(image.transform.localPosition.x, image.transform.localPosition.y, -10));
答案 0 :(得分:3)
这是我最终得到的代码。您问题中的代码是Update()
函数的下半部分。我唯一改变的是传递给ScreenToWorldPoint()
方法的内容。该值在Update()
函数的上半部分计算。
RectTransformToScreenSpace()
函数改编自this Unity Answer post 1 关于获取RectTransform
的屏幕空间坐标(这正是我们想要的从屏幕空间坐标转换回世界空间!)唯一的区别是我得到了反Y值,所以我从Screen.height - transform.position.y
更改为transform.position.y
,完美地完成了这一操作。
之后只需抓住该矩形的左下角,使其成为Vector3而不是Vector2,然后将其传回ScreenToWorldPoint()
。唯一的技巧那里是因为透视相机,我需要知道线路距离相机最近有多远才能保持相同的距离(否则线条)在屏幕上上下移动的速度比图像快。对于正交相机,此值可以是任何值。
void Update () {
//the new bits:
float dist = (Camera.main.transform.position - newListOfPoints[0]).magnitude;
Rect r = RectTransformToScreenSpace((RectTransform)image.transform);
Vector3 v3 = new Vector3(r.xMin, r.yMin, dist);
//more or less original code:
Vector3 val = Camera.main.ScreenToWorldPoint(v3);
for(int i = 0; i < newListOfPoints.Count; i++) {
line.SetPosition(i, new Vector3(newListOfPoints[i].x, val.y, newListOfPoints[i].z));
}
}
//helper function:
public static Rect RectTransformToScreenSpace(RectTransform transform) {
Vector2 size = Vector2.Scale(transform.rect.size, transform.lossyScale);
Rect rect = new Rect(transform.position.x, transform.position.y, size.x, size.y);
rect.x -= (transform.pivot.x * size.x);
rect.y -= ((1.0f - transform.pivot.y) * size.y);
return rect;
}
1 在“我如何获取UI对象的屏幕坐标”的广义搜索中找到 帖子并不容易。一堆其他帖子出现并有一些代码,但没有一个做我想要的(包括将屏幕空间坐标转换回 UI对象的世界空间坐标,这是愚蠢容易而不是反转,谢谢RectTransformUtility
!)