Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to Rescale all UI objects after Canvas Scale mode changed.

Discussion in 'Game Design' started by disappearer, Jan 7, 2021.

  1. disappearer

    disappearer

    Joined:
    Jun 7, 2019
    Posts:
    74
    First of all Save the project, I can't guarantee somethings won't be broken.

    What we will do is scaling and positioning all Images by seting all values of Rect Transforms anchors to their own Image center with this script. It can be used by those who want to reconfigure the screen but this only includes Rect Transforms not Non UI Transforms. Maybe this can help projects which is have a large number of interface elements. I didn't add the dropdown templates because they don't scale as expected.

    create new script named "Tools" in your assets and replace with this script.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using TMPro;
    6. using UnityEditor;
    7.  
    8. public class Tools : MonoBehaviour
    9. {
    10.  
    11.     // attach de children
    12.     public List<RectTransform> parents = new List<RectTransform>();
    13.     private List<Vector2> anchormax = new List<Vector2>();
    14.     private List<Vector2> anchorMin = new List<Vector2>();
    15.     public List<RectTransform> allRT = new List<RectTransform>();
    16.     public List<int> allRTSiblingIndex = new List<int>();
    17.  
    18.     public List<Vector2> savedSizes = new List<Vector2>();
    19.     public List<Vector3> savedPos = new List<Vector3>();
    20.  
    21.  
    22.     // change anchors
    23.     public List<Vector2> savedAnchorsMin = new List<Vector2>();
    24.     public List<Vector2> savedAnchorsMax = new List<Vector2>();
    25.     public List <Vector2> savedPivot = new List<Vector2>();
    26.     public List<Vector3> savedPositions = new List<Vector3>();
    27.     public List<RectTransform> savedRectTransforms = new List<RectTransform>();
    28.  
    29.     public List<Vector3> rectPositionsOfNewScreenSize = new List<Vector3>();
    30.  
    31.  
    32.     [ContextMenu("CHANGE ANCHORS TO IMAGE CENTER")]
    33.     public void changeAnchorsToCenter()
    34.     {
    35.         allRT.Clear();
    36.         allRT.AddRange(Resources.FindObjectsOfTypeAll<RectTransform>());
    37.  
    38.         List<RectTransform> dropdownContents = new List<RectTransform>();
    39.  
    40.         // find dropdown recttransforms
    41.         for (int i = 0; i < allRT.Count; i++)
    42.         {
    43.             if (allRT[i].GetComponent<RectTransform>() != null && !PrefabUtility.IsPartOfAnyPrefab(allRT[i]) && allRT[i].name == "Template")
    44.             {
    45.                 dropdownContents.Add(allRT[i]);
    46.                 dropdownContents.AddRange(allRT.FindAll(x => x.IsChildOf(allRT[i])));
    47.             }
    48.         }
    49.  
    50.         //set all pivots same value for editing local position, pivots determines local position and rotation.
    51.         for (int i = 0; i < allRT.Count; i++)
    52.         {
    53.             if (allRT[i].GetComponent<RectTransform>() != null && !PrefabUtility.IsPartOfAnyPrefab(allRT[i]) && allRT[i].name != "Canvas" && dropdownContents.TrueForAll(x => x != allRT[i]))
    54.             {
    55.                 Vector2 savedPos = new Vector2(allRT[i].localPosition.x + allRT[i].GetComponent<RectTransform>().rect.width * (1 - allRT[i].pivot.x), allRT[i].localPosition.y + allRT[i].GetComponent<RectTransform>().rect.height * (1 - allRT[i].pivot.y));   // kendi rect değerlerinin yarısı eklenerek pozisyon ortaya getiriliyor
    56.                 savedPivot.Add(allRT[i].pivot);
    57.                 savedPositions.Add(allRT[i].position);
    58.                 allRT[i].pivot = new Vector2(1, 1);
    59.                 allRT[i].localPosition = savedPos;
    60.             }
    61.         }
    62.  
    63.         for (int i = 0; i < allRT.Count; i++)
    64.         {
    65.             if (allRT[i].GetComponent<RectTransform>() != null && !PrefabUtility.IsPartOfAnyPrefab(allRT[i]) && allRT[i].name != "Canvas" && dropdownContents.TrueForAll(x => x != allRT[i]))
    66.             {
    67.                 Vector2 tempSize = new Vector2(allRT[i].rect.width, allRT[i].rect.height);
    68.                 Vector3 tempPos = allRT[i].position;
    69.  
    70.                 savedRectTransforms.Add(allRT[i]);
    71.                 // savedPositions.Add(allRT[i].position);
    72.    
    73.                 savedAnchorsMin.Add(allRT[i].anchorMin);
    74.                 savedAnchorsMax.Add(allRT[i].anchorMax);
    75.    
    76.                 Vector2 preAnchorMin = new Vector2(Mathf.Abs(allRT[i].localPosition.x - allRT[i].rect.width / 2) / allRT[i].parent.GetComponent<RectTransform>().rect.width, Mathf.Abs(allRT[i].localPosition.y - allRT[i].rect.height / 2) / allRT[i].parent.GetComponent<RectTransform>().rect.height);
    77.                 Vector2 preAnchorMax = new Vector2(Mathf.Abs(allRT[i].localPosition.x - allRT[i].rect.width / 2) / allRT[i].parent.GetComponent<RectTransform>().rect.width, Mathf.Abs(allRT[i].localPosition.y - allRT[i].rect.height / 2) / allRT[i].parent.GetComponent<RectTransform>().rect.height);
    78.  
    79.                 allRT[i].anchorMin = new Vector2(1 - preAnchorMin.x, 1 - preAnchorMin.y);         /// local poslar pivotlar 1,  1 yaptıktan sonra anchorları doğru yere koymuyor
    80.                 allRT[i].anchorMax = new Vector2(1 - preAnchorMax.x, 1 - preAnchorMax.y);
    81.  
    82.                 allRT[i].SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, tempSize.x);
    83.                 allRT[i].SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, tempSize.y);
    84.  
    85.  
    86.  
    87.                  ///  dropdown içeriklerinin anchorlarını değiştirince posizyon bozuluyor.
    88.                 allRT[i].position = tempPos;
    89.             }
    90.         }
    91.  
    92.         // set all pivots to center
    93.         // for (int i = 0; i < savedPositions.Count; i++)
    94.         // {
    95.         //     Vector3 tempPos = savedRectTransforms[i].localPosition - new Vector3(savedRectTransforms[i].rect.width / 2, savedRectTransforms[i].rect.height / 2 , savedRectTransforms[i].position.z);
    96.         //     savedRectTransforms[i].pivot = new Vector2 (0.5f, 0.5f);
    97.         //     savedRectTransforms[i].localPosition = tempPos;
    98.         // }
    99.  
    100.         // set all pivots to default
    101.         for (int i = 0; i < savedPositions.Count; i++)
    102.         {
    103.             savedRectTransforms[i].pivot = savedPivot[i];
    104.             savedRectTransforms[i].position = savedPositions[i];
    105.         }
    106.     }
    107.  
    108.  
    109.  
    110.     [ContextMenu("CHANGE ANCHORS TO DEFAULT OF NEW SCREEN SIZE")]
    111.     public void changeAnchorsToDefault()
    112.     {
    113.  
    114.         // List<RectTransform> dropdownContents = new List<RectTransform>();
    115.  
    116.         // find dropdown recttransforms
    117.         // for (int i = 0; i < allRT.Count; i++)
    118.         // {
    119.         //     if (allRT[i].GetComponent<RectTransform>() != null && !PrefabUtility.IsPartOfAnyPrefab(allRT[i]) && allRT[i].name == "Template")
    120.         //     {
    121.         //         dropdownContents.Add(allRT[i]);
    122.         //         dropdownContents.AddRange(allRT.FindAll(x => x.IsChildOf(allRT[i])));
    123.         //     }
    124.         // }
    125.  
    126.  
    127.         for (int i = 0; i < savedRectTransforms.Count; i++)
    128.         {
    129.  
    130.             // all pivtos equal 1, 1 in there !
    131.             // if (allRT[i].GetComponent<RectTransform>() != null && !PrefabUtility.IsPartOfAnyPrefab(allRT[i]) && allRT[i].name != "Canvas" && dropdownContents.TrueForAll(x => x != allRT[i]))
    132.             {
    133.                 Vector2 tempSize = new Vector2(savedRectTransforms[i].rect.width, savedRectTransforms[i].rect.height);
    134.                 // Vector3 tempPos = savedRectTransforms[i].localPosition - new Vector3(savedRectTransforms[i].rect.width / 2, savedRectTransforms[i].rect.height / 2 , savedRectTransforms[i].position.z);
    135.  
    136.                 // savedRectTransforms[i].pivot = savedPivot[i];
    137.  
    138.                 savedRectTransforms[i].anchorMin = savedAnchorsMin[i];
    139.                 savedRectTransforms[i].anchorMax = savedAnchorsMax[i];
    140.  
    141.                 savedRectTransforms[i].SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, tempSize.x);
    142.                 savedRectTransforms[i].SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, tempSize.y);
    143.                 // savedRectTransforms[i].position = savedPositions[i];  //RESIZE OF AT SCREEN SIZE
    144.                 savedRectTransforms[i].position = rectPositionsOfNewScreenSize[i];
    145.             }
    146.         }
    147.     }
    148.  
    149.     [ContextMenu("SIZE SETTING ACCORDING TO SCREEN")]   // screen size x = 337.5  y = 600
    150.     public void sizeSettinger()  // new size  x = 187.5  y = 333,75
    151.     {
    152.         float x = 337.5f / 187.5f;   /// values on the left is old screen canvas sizes, values on the right is new sizes;
    153.         float y = 600f / 333f;        ///
    154.  
    155.         for (int i = 0; i < savedRectTransforms.Count; i++)
    156.         {
    157.             Vector2 size = new Vector2 (savedRectTransforms[i].rect.width / x, savedRectTransforms[i].rect.height / y);
    158.             savedRectTransforms[i].SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, size.x);
    159.             savedRectTransforms[i].SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size.y);
    160.             // rectPositionsOfNewScreenSize.Add(savedRectTransforms[i].position);
    161.         }
    162.         // setting font sizes
    163.         float fontSizeFraction = (x + y) / 2;
    164.         List<TextMeshProUGUI> texts = new List<TextMeshProUGUI>(Resources.FindObjectsOfTypeAll<TextMeshProUGUI>());
    165.         for (int i = 0; i < texts.Count; i++)
    166.         {
    167.             if (!PrefabUtility.IsPartOfAnyPrefab(texts[i]))
    168.                 if (texts[i].enableAutoSizing)
    169.                 {
    170.                     texts[i].fontSizeMax = texts[i].fontSizeMax / fontSizeFraction;
    171.                     texts[i].fontSizeMin = texts[i].fontSizeMin / fontSizeFraction;
    172.                 }
    173.                 else
    174.                 {
    175.                     texts[i].fontSize = texts[i].fontSize / fontSizeFraction;
    176.                 }
    177.         }
    178.     }
    179.  
    180.     [ContextMenu("SAVE NEW SIZE POSITIONS")]
    181.     public void saveNewSizePositions()
    182.     {
    183.         for (int i = 0; i < savedRectTransforms.Count; i++)
    184.         {
    185.             rectPositionsOfNewScreenSize.Add(savedRectTransforms[i].position);
    186.         }
    187.     }
    188.  
    189.     // [ContextMenu("CHILDREN DE ATTACHER")]
    190.     public void childrenDeAttacher()
    191.     {
    192.         //CLEAR ALL LISTS
    193.  
    194.         allRT.AddRange(Resources.FindObjectsOfTypeAll<RectTransform>());
    195.  
    196.         //save sibling index of childs
    197.         for (int i = 0; i < allRT.Count; i++)
    198.         {
    199.             if (allRT[i].GetComponent<RectTransform>() != null && !PrefabUtility.IsPartOfAnyPrefab(allRT[i]))
    200.             {
    201.                 allRTSiblingIndex.Add(allRT[i].GetSiblingIndex());
    202.             }
    203.         }
    204.  
    205.         //set parentless
    206.         for (int i = 0; i < allRT.Count; i++)
    207.         {
    208.             if (allRT[i].GetComponent<RectTransform>() != null && !PrefabUtility.IsPartOfAnyPrefab(allRT[i]))
    209.             {
    210.                 if (allRT[i].parent != null)
    211.                     parents.Add(allRT[i].parent.GetComponent<RectTransform>());
    212.                 else
    213.                     parents.Add(null);
    214.                 allRT[i].SetParent(GameObject.Find("Canvas2").transform, false);
    215.  
    216.                 anchormax.Add(allRT[i].anchorMax);
    217.                 anchorMin.Add(allRT[i].anchorMin);
    218.  
    219.                 savedSizes.Add(new Vector2(allRT[i].rect.width, allRT[i].rect.height));
    220.                 savedPos.Add(allRT[i].position);
    221.  
    222.                 // allRT[i].anchorMax = new Vector2(1, 1);
    223.                 // allRT[i].anchorMin = new Vector2(0, 0);
    224.  
    225.                 // allRT[i].SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, savedSizes[i].x);
    226.                 // allRT[i].SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, savedSizes[i].y);
    227.                 allRT[i].position = savedPos[i];
    228.             }
    229.         }
    230.     }
    231.  
    232.  
    233.     // [ContextMenu("CHILDREN ATTACH DE DEFAULT")]
    234.     public void childAttachToDefaultParents()
    235.     {
    236.         for (int i = 0; i < allRT.Count; i++)
    237.         {
    238.             if (allRT[i].GetComponent<RectTransform>() != null && !PrefabUtility.IsPartOfAnyPrefab(allRT[i]))
    239.             {
    240.                 allRT[i].SetParent(parents[i], false);
    241.                 // allRT[i].anchorMax = anchormax[i];
    242.                 // allRT[i].anchorMin = anchorMin[i];
    243.                 // allRT[i].SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, savedSizes[i].x);
    244.                 // allRT[i].SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, savedSizes[i].y);
    245.                 allRT[i].position = savedPos[i];
    246.             }
    247.         }
    248.         // set sibling index of childs
    249.         for (int i = 0; i < allRT.Count; i++)
    250.         {
    251.             if (allRT[i].GetComponent<RectTransform>() != null && !PrefabUtility.IsPartOfAnyPrefab(allRT[i]))
    252.             {
    253.                 allRT[i].SetSiblingIndex(allRTSiblingIndex[i]);
    254.             }
    255.         }
    256.     }
    257. }
    258.  


    1. Then create a gameobject on the main directory and place the script inside.

    2. Check out canvas values.
    Since the screen scale mode is adjusted according to the width here, it can be taken as this.

    3. Also save the values of desired screen scale mode canvas values.

    4. Then write these values in this part of script of tools

    5. In here , Keep the screen settings as they are during the whole process.
    Click the "change anchors to image center" option in tools.

    6. Now set the only main canvas child rect transforms anchor values to the middle,these are not adjusted because of main canvas.

    7. Now, click the "size settings according to screen option" in tools, so all rect objects sized as desired screen scale values. There may be a little lapses in between, also I cofigured font sizes for TextMeshGui Pro.
    If you use normal text components, you can change from script.

    8. After than that, switch to the canvas scale mode you have chosen previously.

    9. Save the value of adjusted rect positions, it necessary for resetting anchors at this point.

    10. After all, click the "Change anchors to default of new screen size" in tools.

    now is process is completed, but all references size on the tools script should be set to zero if repeat all of this.

    screenshots are attached below
     

    Attached Files:

    Last edited: Sep 7, 2022