简体   繁体   中英

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

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;

}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM