0

How to keep a pop up window on the screen? (Unity 2D, UI Image, Screen space overlay)

I have a pop up window 225x172 that I enable and change its transform to the mouse position as a pop up window.

The problem I have is that if a user clicks near the screen edge, the pop up window isn't fully visible on the screen, as parts of its length and width will be out of the visible area.

Solution is to check for the borders and adjust the pop up windows location to ensure for its length and width it appears as close to the mouse as possible but always fully visible.

I wrote a function to return the adjusted Vector3, and it works ok until I adjust the screen resolution, and then it starts placing it in different non optimal positions.

I guess I have to put some sort of scaling in? I imagine this is fairly common problem, but googling for a few hours hasn't given me any solutions...

Anyone got a solution? Here is my method:

   private Vector3 KeepOnScreen(Vector3 MyInputPos, int width, int Height)   // returns vector3 always on screen
{
    var corners = new Vector3[4];
    var RetRec = new Vector3();
    RetRec = MyInputPos;

    GetComponent<RectTransform>().GetWorldCorners(corners);
    // This returns the world space positions of the corners in the order
    // [0] bottom left, [1] top left [2] top right [3] bottom right

    int xmin = Mathf.RoundToInt(corners[0].x);
    int xmax = Mathf.RoundToInt(corners[2].x);
    int ymin = Mathf.RoundToInt(corners[2].y);
    int ymax = Mathf.RoundToInt(corners[3].y);

    //Debug.Log($" MINS {xmin} {ymin}");
    //Debug.Log($" MAXS {xmax} {ymax}");
    //Debug.Log($" Mouse {MyInputPos.x} {MyInputPos.y}");

    RetRec.y = RetRec.y-20 - Height*2;  // move a bit to the right and down so the pop up window is not under mouse
    RetRec.x = RetRec.x + 40;
    if (MyInputPos.x + width*2 > xmax) { RetRec.x = xmax - width * 2 - 40;} // adjust to keep whole window on screen
    if (MyInputPos.y -Height < ymax) { RetRec.y = MyInputPos.y;}

    return RetRec;

}
Ratbyte Boss
  • 461
  • 4
  • 13
  • So. If you know the size of the pop up. You can tell if x+width> screen size or x-width is < 0 etc and move it by the appropriate amount to bring it fully on screen – BugFinder Aug 17 '22 at 07:59

1 Answers1

3

Ok after may hours of searching I ended up with the following method that pops up the UI element near the mouse but keeps it on the screen.

Pass it your mouse position (Input.mousePosition), the popup windows RectTransform, and the RectTransform of the canvas your panel is on.

void ClampToWindow( Vector3 MyMouse,  RectTransform panelRectTransform, RectTransform parentRectTransform)
{

    panelRectTransform.transform.position  = MyMouse;

    Vector3 pos = panelRectTransform.localPosition;

    Vector3 minPosition = parentRectTransform.rect.min - panelRectTransform.rect.min;
    Vector3 maxPosition = parentRectTransform.rect.max - panelRectTransform.rect.max;

    pos.x = Mathf.Clamp(panelRectTransform.localPosition.x, minPosition.x, maxPosition.x);
    pos.y = Mathf.Clamp(panelRectTransform.localPosition.y, minPosition.y, maxPosition.y);

    panelRectTransform.localPosition = pos;
} 
Ratbyte Boss
  • 461
  • 4
  • 13
  • Good solution. However, I feel as though it needs to also swap pivot points depending upon usage. – Krythic Jun 16 '23 at 01:28