Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Adjusting rect transform with sreen resolution

Discussion in 'UGUI & TextMesh Pro' started by JevinLevin_, Sep 28, 2023.

  1. JevinLevin_

    JevinLevin_

    Joined:
    Jan 18, 2023
    Posts:
    10
    I have this system to calculate the area of 3 overlapping RectTransforms, and then set the size of a new RectTransforms to be the overlapping area.

    Code (CSharp):
    1.     private Rect CheckOverlap()
    2.     {
    3.         CalculateScale();
    4.  
    5.         Rect rect1 = new Rect(rectRed.position.x * scaleX, rectRed.position.y * scaleY, rectRed.rect.width, rectRed.rect.height);
    6.         Rect rect2 = new Rect(rectBlue.position.x * scaleX, rectBlue.position.y * scaleY, rectBlue.rect.width, rectBlue.rect.height);
    7.         Rect rect3 = new Rect(rectOrange.position.x * scaleX, rectOrange.position.y * scaleY, rectOrange.rect.width, rectOrange.rect.height);
    8.  
    9.         // Initialize an empty rectangle for the overlapping area
    10.         Rect overlappingRect = Rect.zero;
    11.  
    12.         overlappingRect = Rect.MinMaxRect(
    13.             Mathf.Max(rect1.xMin, rect2.xMin),
    14.             Mathf.Max(rect1.yMin, rect2.yMin),
    15.             Mathf.Min(rect1.xMax, rect2.xMax),
    16.             Mathf.Min(rect1.yMax, rect2.yMax)
    17.         );
    18.  
    19.         overlappingRect = Rect.MinMaxRect(
    20.             Mathf.Max(overlappingRect.xMin, rect3.xMin),
    21.             Mathf.Max(overlappingRect.yMin, rect3.yMin),
    22.             Mathf.Min(overlappingRect.xMax, rect3.xMax),
    23.             Mathf.Min(overlappingRect.yMax, rect3.yMax)
    24.         );
    25.  
    26.         overlappingRect.position = new Vector2((overlappingRect.position.x - rect1.size.x/2 + overlappingRect.size.x/2) / scaleX, (overlappingRect.position.y - rect1.size.y/2 + overlappingRect.size.y/2) / scaleY);
    27.         return overlappingRect;
    28.  
    29.     }
    Code (CSharp):
    1.         overlapRectTransform.position = overlapRect.position;
    2.  
    3.         overlapRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, overlapRect.width);
    4.         overlapRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, overlapRect.height);
    Now this works if i switch from 1080p to 4k, however the sizes are slightly off if I change aspect ratio (to ultrawide for example)

    I'm really stumped and it took me long enough to figure out scaling it for 1080/4k, any ideas how I can fix this?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,256
    Oh my goodness, don't touch that RectTransform stuff in code... it's toxic waste.

    Just use the layouts and anchors and CanvasScaler.

    Here are some notes on UI Anchoring, Scaling, CanvasScaler, etc:

    https://forum.unity.com/threads/inc...size-between-two-people.1130146/#post-7261747

    https://forum.unity.com/threads/game-ui-button-size-problem.1142650/#post-7337383

    Usually you need to choose a suitable ScaleMode and MatchMode in the Canvas Scaler and stick with it 100%. Generally if you change those settings you will often need to redo your UI entirely.

    I also use this
    CanvasScalerOrientationDriver
    utility to make sharing UI for Landscape / Portrait easier. Read what it does carefully.

    https://gist.github.com/kurtdekker/8802b1b6c708637398f8c9167641efd3

    Some more reading:

    Instantiating things into a UnityEngine.UI (aka, com.unity.ugui) Canvas hierarchy:

    Everything instantiated in a UI MUST be parented to something valid in the hierarchy.

    Therefore, if you instantiate prefabs into your UI hierarchy, always use the version of Instantiate that takes two arguments, with the second argument being the parent.

    ALWAYS supply a valid under-a-canvas parent Transform where you want the UI chunk to appear.

    Supplying positions to anything in UI space via code is almost always an exercise in futility. This is due to the inscrutable nature of the RectTransform object and how it interacts with other RectTransforms, anchors, and the CanvasScaler as well as the canvas mode.

    You are of course welcome to supply positions but it is on you to test on EVERY possible combination of aspect ratio and resolution to verify your positioning and anchoring. Expect it to fail if you do not do this testing.

    Instead of supplying positions, either use a flavor of the Layout family of components to position things automatically, or else use invisible pre-existing Transforms in your UI as positional inputs.
     
  3. JevinLevin_

    JevinLevin_

    Joined:
    Jan 18, 2023
    Posts:
    10
    The issue is I have no idea how to position the element using just anchoring, is there something I'm missing? I feel like using a script is the only way to reliably get this pink area upload_2023-9-28_21-14-29.png