web-dev-qa-db-fra.com

Obtenir une position UnityEngine.UI.Images dans screenSpace et calculer un décalage normalisé (à l'intérieur d'un canevas de superposition)

Le problème à résoudre:

Simplifié

Étant donné un UnityEngine.Ui.Image Comment trouver la position X, Y D’un décalage normalisé (comme 0.4, 0.3 en haut à gauche) à l’intérieur de cette image Dans des unités ScreenSpace comme 400 300

Je suppose que je dois trouver la valeur ScreenSpace en haut à gauche , Puis connaître la taille totale affichée de l'image et redimensionner les décalages normalisés en fonction du rapport de taille réel exprimé en pixels.

Figure 1:  Figure 1:

La figure 2 montre les offsets normalisés à utiliser.

Figure 2:  An example stored Rect "offset"

Donc, précisément, je dois trouver le décalage dans les pixels de ScreenSpace du TopLeft du Rect que j'ai stocké contre l'image.

Je reconnais que c’est probablement une combinaison de Camera.main.ViewportToWorldPoint () et de quelques références aux limites, Qui est éventuellement mise à l’échelle par backgroundImage.Sprite.pixelsPerUnit?

Luttant pour visualiser comment faire exactement cela.

merci

16
twobob

Je suppose que vous n’avez pas d’échelle ni de rotation dans l’image parent et que la position Y est 0.

D'abord, vous pouvez obtenir la position du coin supérieur gauche de votre image avec rectTransform.GetWorldCorners():

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

Ensuite, vous devez transformer votre décalage normalisé en un espace mondial compensé par un rapport entre la taille de votre image et la taille de votre rect et ajoutez la position du coin supérieur gauche:

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

(Il en va de même pour la coordonnée Y, mais vous devez soustraire selon votre ratio realOffsetY car le décalage est calculé à partir du coin supérieur gauche.)

Voici la méthode complète:

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

Ensuite, si vous voulez que cet espace mondial utilise de l'espace, utilisez la méthode de la caméra:

camera.WorldToScreenPoint(positionOffset);
1
Ludovic Feltz