Search Unity

Bug with PanelSetting ScaleWithScreen/Exapand it scales nonuniformly and problems near screen size

Discussion in 'UI Toolkit' started by Ryuuguu, Sep 28, 2020.

  1. Ryuuguu

    Ryuuguu

    Joined:
    Apr 14, 2007
    Posts:
    391
    When PanelSetting scale mode is scale with screenSize and screen match mode is expand the scaling does not work properly when the screen size in near or below the PanelSetting reference size.
    [Edit]: Also found problems with shrink but I have not yet been able to make a simple example to show it. Run time (tested Windows and WebGL) also seem to have more problems than in the Editor.

    Video example. As I resize the windows instead of resizing smaller it doubles in vertical scale then doubles in horizontal scale then get s small and finally disappears.


    To reproduce place this Monobehaviour on a game object with a UIDocument.
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UIElements;
    3.  
    4. public class ExampleUILayout3 : MonoBehaviour {
    5.     void Start() {
    6.         var root = GetComponent<UIDocument>().rootVisualElement;
    7.         var ve = new VisualElement();
    8.         ve.style.position = Position.Absolute;
    9.         ve.style.width = 1;
    10.         ve.style.height = 1;
    11.         ve.style.backgroundColor = Color.green;
    12.         ve.transform.scale = Vector3.one * 100;
    13.         root.Add(ve);
    14.     }
    15. }
     
    Last edited: Sep 28, 2020
  2. Ryuuguu

    Ryuuguu

    Joined:
    Apr 14, 2007
    Posts:
    391
    After some more checking. In the Editor Shrink does not work when both sides are small, expand does work when either side is small and in Runtime neither works ever. I have written a short test that works in the editor with large windows and shows what goes wrong when in Runtime. To see how things should look run it first in the editor with a small PanelSetting reference screen size and large game window. Then build to see Runtime. just put this monobehaviour on a game object with a UIDocument.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Security.Permissions;
    4. using UnityEngine;
    5. using UnityEngine.Serialization;
    6. using UnityEngine.UIElements;
    7.  
    8. public class ExampleUILayout2 : MonoBehaviour {
    9.     public Vector2 mapRatio;
    10.     public float scale = 10;
    11.  
    12.     private VisualElement _root;
    13.     private VisualElement _mapHolder;
    14.     private VisualElement _detailsHolder;
    15.  
    16.     void Start() {
    17.         Init();
    18.      
    19.         // add first call using panel utility
    20.     }
    21.  
    22.     /// <summary>
    23.     /// scale and position a toplevel elements after geomtry change
    24.     /// create them if they do not exist.
    25.     /// </summary>
    26.     /// <param name="screenRect"></param>
    27.     private void TopLevelLayout(Rect screenRect) {
    28.         if (_mapHolder == null) {
    29.             _mapHolder = SquareVE( Color.green);
    30.             _root.Add(_mapHolder);
    31.              MakeGrid(_mapHolder);
    32.              Debug.Log( "made");
    33.         }
    34.         ScaleMapHolder(_mapHolder, mapRatio, screenRect.max);
    35.     }
    36.  
    37.     private void MakeGrid(VisualElement parent) {
    38.         for (int i = 0; i < mapRatio.x; i++) {
    39.             for (int j = 0; j < mapRatio.y; j++) {
    40.                 var color = new Color(1,0,0,0.5f);
    41.                 if ((i + j) % 2 ==0) {
    42.                     color = new Color(0,1,1,0.5f);
    43.                 }
    44.                 var ve =  SquareVE(color);
    45.                 var pos = (new Vector3(i, j , 0))*scale;
    46.                 ve.transform.position = pos;
    47.                 ve.transform.scale =  Vector3.one*scale*0.8f;
    48.                 parent.Add(ve);
    49.             }
    50.         }
    51.      
    52.     }
    53.     /// <summary>
    54.     /// Setup root and callbacks
    55.     /// </summary>
    56.     private void Init() {
    57.         _root = GetComponent<UIDocument>().rootVisualElement;
    58.         _root.RegisterCallback<GeometryChangedEvent>( (evt) => TopLevelLayout(evt.newRect));
    59.     }
    60.  
    61.     private void ScaleMapHolder(VisualElement ve,Vector2 holderSize, Vector2 parentSize) {
    62.         var parentRatio = parentSize.x / parentSize.y;
    63.         var holderRatio = holderSize.x / holderSize.y;
    64.         var rescale = 1f;
    65.         if (holderRatio > parentRatio) {
    66.             rescale = parentSize.x/holderSize.x;
    67.         }
    68.         else {
    69.             rescale = parentSize.y/holderSize.y;
    70.         }
    71.         Debug.Log("holderElement: "+ ve.localBound  + " _root (evt.newRect: "+ parentSize);
    72.         ve.transform.scale = rescale * Vector3.one;
    73.      
    74.         Debug.Log("Screen.safeArea: "+ Screen.safeArea  + " rescale: "+ rescale);
    75.     }
    76.  
    77.     private VisualElement SquareVE( Color color) {
    78.         var ve = new VisualElement();
    79.         ve.style.position = Position.Absolute;
    80.         ve.style.width = 1;
    81.         ve.style.height = 1;
    82.         ve.style.backgroundColor = color;
    83.         return ve;
    84.     }
    85. }
    86.  
     
  3. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    700
    Hello, thanks for reporting it! We've opened a bug on our tracker and I'll share a public link when I have one so you can follow the status.
     
    Ryuuguu likes this.
  4. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    700
    Hello again Ryuuguu, I'm trying to investigate the issue but I have an important question - does the weird scaling of the square only happen when you're resizing the window? As in, if you stop resizing, does the square always show up properly, or is it still weirdly shaped sometimes?

    Thanks in advance!
     
  5. Ryuuguu

    Ryuuguu

    Joined:
    Apr 14, 2007
    Posts:
    391
    When you stop resizing it keeps the wrong size & shape. Also on Windows & WebGL builds there are similar problems but not quite the same. The squares in the code from the code in my second post alternate between getting large and smaller relative to their position as the Window get smaller.
     
  6. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    700
    Thanks for your reply. Can you try your examples without touching the transform.scale of the VisualElement, but setting the style.width and style.height instead?
     
  7. Ryuuguu

    Ryuuguu

    Joined:
    Apr 14, 2007
    Posts:
    391
    If I change the change the code to
    Code (CSharp):
    1.         ve.style.width = 100;
    2.         ve.style.height = 100;
    3.         ve.style.backgroundColor = Color.green;
    4.         ve.transform.scale = Vector3.one ;
    There are no problems with the above code. For me, this is not a useable workaround, it would mean writing code to emulate changing transform.scale by changing all the children's positions and width and height of every element. For now, I am switching to constant Pixelsize for PanelSetting scale mode. I suspect this would force me to resize fonts in my code so I will try putting the text on a separate UIDocument that uses scale with screen.