Search Unity

Bug Mouseover interactions misaligned with right-aligned content (build only)

Discussion in 'UGUI & TextMesh Pro' started by kierenj, Aug 27, 2022.

  1. kierenj

    kierenj

    Joined:
    Jul 7, 2013
    Posts:
    13
    I have a Screen Space - Overlay canvas with some right-aligned buttons:

    upload_2022-8-27_9-5-43.png

    upload_2022-8-27_8-54-38.png

    The container looks like this:

    upload_2022-8-27_8-55-0.png

    Each button looks like this:

    upload_2022-8-27_8-55-35.png

    Conditions:

    - Built player only (it seems)
    - Window needs to be maximised, or fairly large
    - Is dependant on the X Pos of the ToolIcons container. Depending on window resolution, it can be something like XPos of -116 - all works fine, -117 ... it's broken

    The problem:

    - While rendering is fine, mouse-over interactions (highlights, clicks) are misaligned. *usually*, the Y coord is offset such that the button *below* highlights the button *above*
    - This includes the fact that the cursor over the top icon does nothing, and moving the mouse over the space beneath the bottom icon highlights the bottom icon
    - Depending on X Position of the right-align, or window size, sometimes it'll instead be that the Y offset is gone, but only the left half of the icons trigger the interactions

    It does *seem* like a bug - surely the same layout values and logic should be used for rendering and hit-testing?

    I have tried:

    - Trying to recreate in editor play mode
    - Checking console for any warning/error output - none
    - Disabling the custom DP Canvas Scaler / using a regular canvas scaler
    - A few hours' googling/forum searching
    - Playing with anchor/pivot settings on the buttons
    - Checking all the transforms have a scale of 1, no rotation, etc
    - Weeping gently

    My questions:

    - Is anyone aware of this scenario / bug?
    - Any suggestions for diagnosing further?
     
  2. kierenj

    kierenj

    Joined:
    Jul 7, 2013
    Posts:
    13
    Update - it's not just those buttons. The right-hand side of the screen, even at 1080p resolution - a Y offset is introduced as I move the cursor to the right.

    E.g. if I have a list of dropdowns in a modal window near the right.. when I move the mouse across the width of one, the current (correct) dropdown starts off highlighted, but as I go to the right, the one above does instead.

    How/why would there be Y offset "warping" at the right-hand side of the screen??

    UPDATE - I added some debug output to show Mouse.current.position, the GraphicRaycaster.Raycast first result's screenPosition, and the offset between the two:

    When the mouse cursor X is 1857 or greater, the raycast screenPosition's Y value gets an offset of 35.
     
    Last edited: Aug 28, 2022
  3. kierenj

    kierenj

    Joined:
    Jul 7, 2013
    Posts:
    13
    Ok, I've been debugging the raycast code. it's MultipleDisplayUtilies.RelativeMouseAtScaled that applies the offset. It has conditional logic for build mode only.

    Below is the Unity code where the bug is.

    See the comment, "If we are not inside of the main display". This clause is triggered and adds an offset. However, the assumption is faulty: we ARE inside the main display.

    That means "widthPlusRightPadding" is incorrect.

    My values:

    Screen.fullScreen = false
    Display.main.renderingWidth = 1920
    Display.main.renderingHeight = 1009
    Display.main.systemWidth = 1920
    Display.main.systemHeight = 1080

    widthPlusPadding = 1793
    widthPlusRightPadding = 1856

    I don't know what "padding" its referring to here. But my renderingWidth is 1920, my systemWidth is 1920, I don't know why any offset is applied at "widthPlusRightPadding".

    Code (CSharp):
    1.  
    2.             // If the main display is now the same resolution as the system then we need to scale the mouse position. (case 1141732)
    3.             if (Display.main.renderingWidth != Display.main.systemWidth || Display.main.renderingHeight != Display.main.systemHeight)
    4.             {
    5.                 // Calculate any padding that may be added when the rendering apsect ratio does not match the system aspect ratio.
    6.                 int widthPlusPadding = Screen.fullScreen ? Display.main.renderingWidth : (int)(Display.main.renderingHeight * (Display.main.systemWidth / (float)Display.main.systemHeight));
    7.  
    8.                 // Calculate the padding on each side of the screen.
    9.                 int padding = Screen.fullScreen ? 0 : (int)((widthPlusPadding - Display.main.renderingWidth) * 0.5f);
    10.                 int widthPlusRightPadding = widthPlusPadding - padding;
    11.  
    12.                 // If we are not inside of the main display then we must adjust the mouse position so it is scaled by
    13.                 // the main display and adjusted for any padding that may have been added due to different aspect ratios.
    14.                 if ((position.y < 0 || position.y > Display.main.renderingHeight ||
    15.                      position.x < 0 || position.x > widthPlusRightPadding))
    16.                 {
    17.                     if (!Screen.fullScreen)
    18.                     {
    19.                         // When in windowed mode, the window will be centered with the 0,0 coordinate at the top left, we need to adjust so it is relative to the screen instead.
    20.                         position.x -= (Display.main.renderingWidth - Display.main.systemWidth) * 0.5f;
    21.                         position.y -= (Display.main.renderingHeight - Display.main.systemHeight) * 0.5f;
    22.                     }
     
  4. kierenj

    kierenj

    Joined:
    Jul 7, 2013
    Posts:
    13
    Ok, finding that method led me to:

    https://forum.unity.com/threads/mou...ght-side-of-screen-in-windowed-build.1324008/.

    I also raised incident IN-15001.


    And the temporary fix;

    A fix is on the way. You can work around the issue now by moving the UGUI package from the PackageCache folder into the projects Packages folder. Then replace the file MyProject\Packages\com.unity.ugui\Runtime\UI\Core\MultipleDisplayUtilities.cs with this one https://gist.github.com/karljj1/e333a7a3f192a5d264d95bfbaff0fde8