获取屏幕空间中的 UnityEngine.UI.Images 位置并计算归一化偏移量(在叠加层内 canvas)

Get a UnityEngine.UI.Images position in screenSpace and calculate a normalised offset (inside an overlay canvas)

手头的问题:

简化

Given an UnityEngine.Ui.Image How does one find the X,Y position of a normalised offset (like 0.4, 0.3 from the top left) inside that image in ScreenSpace units like 400,300

我想我需要找到左上角的 ScreenSpace 值 然后知道图像的渲染总大小按以像素表示的实际大小比例缩放归一化偏移。

图一:

图 2 显示了要使用的 normalisedOffsets

图2:

So, in precis, I need to find the offset in ScreenSpace pixels of the topLeft of the Rect I have stored against the image.

我认识到它可能是 Camera.main.ViewportToWorldPoint() 和一些对边界的引用的组合, 可能将其缩放 backgroundImage.sprite.pixelsPerUnit?

努力想象如何准确地完成这项工作。

谢谢

我猜你的图像父级没有任何缩放或旋转,位置 Y 为 0。

首先你可以通过rectTransform.GetWorldCorners()得到图片左上角的位置:

    //Upper left corner
    Vector3[] v = new Vector3[4];
    image.rectTransform.GetWorldCorners(v);
    var recPos = v[1];

然后你必须将你的标准化偏移量转换为一个世界 space 偏移量,偏移量为你的图像大小和你的矩形大小之间的比率,并添加左上角的位置:

    var recWidth = image.rectTransform.sizeDelta.x;
    var imgWidth = image.sprite.texture.width;
    var realOffsetX = offsetX * (recWidth / imgWidth);
    var realPosX = recPos.x + realOffsetX;

(与 Y 坐标的公式相同,但您必须减去您的比率 realOffsetY,因为偏移量是从左上角计算的)

完整方法如下:

private Vector3 GetPositionOffset(Image image, float offsetX, float offsetY)
{
    //Upper left corner
    Vector3[] v = new Vector3[4];
    image.rectTransform.GetWorldCorners(v);
    var recPos = v[1];

    //X coordinate
    var recWidth = image.rectTransform.sizeDelta.x;
    var imgWidth = image.sprite.texture.width;
    var realOffsetX = offsetX * (recWidth / imgWidth);
    var realPosX = recPos.x + realOffsetX;

    //Y coordinate
    var recHeight = image.rectTransform.sizeDelta.y;
    var imgHeight = image.sprite.texture.height;
    var realOffsetY = offsetY * (recWidth / imgWidth);
    var realPosY = recPos.y - realOffsetY;

    //Position
    return new Vector3(realPosX, realPosY, image.transform.position.z);
}

那么如果你想让这个世界space屏幕space只需要使用相机方法:

camera.WorldToScreenPoint(positionOffset);