How to calculate a child UI image's anchoredPosition(?) based on screen position input?

I'm trying to have the child UI image (Spotlight) show up where the eyeball UI is, but it seems to always be offset. The eyeball correctly shows up based on the Screen Position.

enter image description here

It is perfect when the Canvas is at 1080x1920 (set to scale)

But when I try it using others screen resolutions such as 1125x2436, the issue above shows up.

None of these attempts work. The gif is based on the one not commented out here:

p=Input.mousePosition; // screenPosition 

    public static void SetRTPos(Transform g,Vector2 p,Canvas c)
        RectTransform rt = g.GetComponent<RectTransform>();
        rt.anchorMin = Vector2.zero;rt.anchorMax = Vector2.zero;
        rt.pivot = Vector2.zero;
        // rt.anchoredPosition = RectTransformUtility.PixelAdjustPoint(p,g.parent,c);
        //rt.anchoredPosition = new Vector2(p.x* (float)c.pixelRect.x, p.y*(float)c.pixelRect.y);//  c.scaleFactor;
        rt.anchoredPosition = new Vector2(p.x*1080f/Screen.width,p.y*1920f/Screen.height );
        //rt.localPosition = RectTransformUtility.ScreenPointToLocalPointInRectangle(rt.parent.GetComponent<RectTransform>(),p,Camera.main,out p2)

The UI RectTransform for rt.parent: enter image description here

The UI RectTransform for g (not the x,y,z are updated at runtime): enter image description here

  • \$\begingroup\$ Can you show us where the vector p comes from, so there's no ambiguity? It would also help to see how you've configured the RectTransform of the spotlight, and the bounds of its parent. \$\endgroup\$
    – DMGregory
    Aug 11 '20 at 10:17
  • \$\begingroup\$ p=Input.mousePosition - updated \$\endgroup\$
    – ina
    Aug 11 '20 at 17:30

You had the right answer, you just used it wrong. ScreenPointToLocalPointInRectangle returns a boolean true/false, indicating whether the point is in the rectangle. To get its position inside that rectangle, you need to read the out parameter.

public static void SetRTPos(/*ask for the type you want*/ RectTransform rt, Vector2 p, Canvas c)
    var center = new Vector2(0.5f, 0.5f);
    rt.anchorMin = center;
    rt.anchorMax = center;
    rt.pivot = center;

        (RectTransform)rt.parent, // No GetComponent needed, just cast it.
        Camera.main,              // Use null if canvas is Screenspace Overlay.
        out Vector2 localPoint    // The position is given as an out parameter.

    rt.anchoredPosition = localPoint;
  • \$\begingroup\$ the spotlight is not showing up at all... and the x values are negative \$\endgroup\$
    – ina
    Aug 11 '20 at 20:01
  • \$\begingroup\$ this involves the scenegraph - would it matter if the rt.parent is set to relative vs absolute? \$\endgroup\$
    – ina
    Aug 11 '20 at 23:13
  • \$\begingroup\$ I've struggled a lot to understand how the pieces of the UI system work together in alignment as child objects with variable screen resolutions - often times I just fumble with anchor min/max/pivot and sometimes that is the easy fix. I'd like to understand them better. \$\endgroup\$
    – ina
    Aug 11 '20 at 23:56
  • \$\begingroup\$ Just tested this and it works as expected in my tests with 0.5 for the pivot/min/max. Just be sure if you're using a Canvas in Screenspace Overlay mode that you heed the docs: "For a RectTransform in a Canvas set to Screen Space - Overlay mode, the cam parameter should be null." \$\endgroup\$
    – DMGregory
    Aug 12 '20 at 0:52
  • \$\begingroup\$ yes the key thing is setting the pivot min/max correctly. assigning a camera in screen space - camera mode seems fine. \$\endgroup\$
    – ina
    Aug 12 '20 at 3:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .