如何将新的Canvas ui图像位置转换为线性渲染器位置? [英] How to convert new Canvas ui image position to linerenderer position?

查看:99
本文介绍了如何将新的Canvas ui图像位置转换为线性渲染器位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在具有屏幕空间-相机"渲染模式的画布中有一个图像UI.我想做的是通过遍历所有LineRenderer位置并更改其y轴,将LineRenderer移至图像垂直位置.我的问题是我无法获得LineRenderer可以理解的图像的正确位置.我尝试使用ViewportToWorldPointScreenToWorldPoint,但是位置不同.

I have an image UI in a canvas with Screen Space - Camera render mode. What I like to do is move my LineRenderer to the image vertical position by looping through all the LineRenderer positions and changing its y axis. My problem is I cant get the correct position of the image that the LineRenderer can understand. I've tried using ViewportToWorldPoint and ScreenToWorldPoint but its not the same position.

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

绿色LineRenderer是更改y位置的结果.它应该在正方形图像的底部.

The green LineRenderer is the result of changing the y position. It should be at the bottom of the square image.

推荐答案

哇,这很烦人而且很复杂.

Wow, this was annoying and complicated.

这是我最终得到的代码.您问题中的代码是Update()函数的下半部分.我唯一更改的是传递给ScreenToWorldPoint()方法的内容.该值在Update()函数的上半部分计算.

Here's the code I ended up with. The code in your question is the bottom half of the Update() function. The only thing I changed is what was passed into the ScreenToWorldPoint() method. That value is calculated in the upper half of the Update() function.

RectTransformToScreenSpace()函数改编自此Unity Answer 帖子 1 关于获取RectTransform的屏幕空间坐标(这正是我们想要从屏幕空间坐标转换回世界空间的目的!)唯一的不同是我得到了反Y值,所以我从Screen.height - transform.position.y更改为transform.position.y,完美地完成了窍门.

The RectTransformToScreenSpace() function was adapted from this Unity Answer post1 about getting the screen space coordinates of a RectTransform (which is exactly what we want in order to convert from screen space coordinates back into world space!) The only difference is that I was getting inverse Y values, so I changed from Screen.height - transform.position.y to just transform.position.y which did the trick perfectly.

此后,只需抓住矩形的左下角,将其设为Vector3而不是Vector2,然后将其传递回ScreenToWorldPoint(). 那里的唯一技巧是因为使用了透视相机,所以我需要知道该线与相机的距离有多远,以便保持相同的距离(否则该线在屏幕上上下移动的速度比图像快).对于正交摄影机,此值可以是任何值.

After that it was just a matter of grabbing that rectangle's lower left corner, making it a Vector3 instead of a Vector2, and passing it back into ScreenToWorldPoint(). The only trick there was because of the perspective camera, I needed to know how far away the line was from the camera originally in order to maintain that same distance (otherwise the line moves up and down the screen faster than the image). For an orthographic camera, this value can be anything.

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 !)

1And finding that post from a generalized search on "how do I get the screen coordinates of a UI object" was not easy. A bunch of other posts came up and had some code, but none of it did what I wanted (including converting screen space coordinates back into world space coordinates of the UI object which was stupid easy and not reversibe, thanks RectTransformUtility!)

这篇关于如何将新的Canvas ui图像位置转换为线性渲染器位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆