Search Unity

[Script] Simple script that automatically adjust anchor to GUI object size (Rect Transform)

Discussion in 'UGUI & TextMesh Pro' started by porygon, Sep 21, 2014.

  1. porygon

    porygon

    Joined:
    Dec 28, 2013
    Posts:
    4
    I have been playing around with the new GUI in 4.6. I have found out that there is no automation that allows the user to surround a GUI object (panel, button, etc.) with anchors on all sides. This would effectively make GUI object scales and stay at the same position relatively to the screen size. Therefore, I wrote a simple script that help me do that, hope this help,

    Note: This only applies to GUI object with parents.. do not apply it on the root canvas



    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class UGUIMenu : MonoBehaviour
    6. {
    7.     [MenuItem ("UI/Anchor Around Object")]
    8.     static void uGUIAnchorAroundObject()
    9.     {
    10.         var o = Selection.activeGameObject;
    11.         if (o != null && o.GetComponent<RectTransform>() != null)
    12.         {
    13.             var r = o.GetComponent<RectTransform>();
    14.             var p = o.transform.parent.GetComponent<RectTransform>();
    15.            
    16.             var offsetMin = r.offsetMin;
    17.             var offsetMax = r.offsetMax;
    18.             var _anchorMin = r.anchorMin;
    19.             var _anchorMax = r.anchorMax;
    20.            
    21.             var parent_width = p.rect.width;      
    22.             var parent_height = p.rect.height;  
    23.            
    24.             var anchorMin = new Vector2(_anchorMin.x + (offsetMin.x / parent_width),
    25.                                         _anchorMin.y + (offsetMin.y / parent_height));
    26.             var anchorMax = new Vector2(_anchorMax.x + (offsetMax.x / parent_width),
    27.                                         _anchorMax.y + (offsetMax.y / parent_height));
    28.            
    29.             r.anchorMin = anchorMin;
    30.             r.anchorMax = anchorMax;
    31.            
    32.             r.offsetMin = new Vector2(0, 0);
    33.             r.offsetMax = new Vector2(1, 1);
    34.             r.pivot = new Vector2(0.5f, 0.5f);
    35.            
    36.         }
    37.     }
    38. }
    39.  
     

    Attached Files:

  2. Text

    Text

    Joined:
    Sep 22, 2014
    Posts:
    2
    Hi thank you for script but you should change this : r.offsetMax = new Vector2(1, 1);
    into this r.offsetMax = new Vector2(0, 0); overwise ui element scales slitly and after performing this script
    several times ui element complitly changes it size .
     
  3. LVBen

    LVBen

    Joined:
    Apr 1, 2013
    Posts:
    16
    Awesome! Thank you so much to both of you! This is going to save me lots of time adjusting anchors!
     
  4. Deleted User

    Deleted User

    Guest

    Thank you very much! I have tested it on Unity 5.3.4f1 and it works perfectly.
    This is the tool number one for me, I am really happy for your kindness :)
     
  5. gvaughan

    gvaughan

    Joined:
    Jan 28, 2010
    Posts:
    32
    Works great for me too! I'm using it at runtime to readjust after dragging an element - much cleaner than the mess I started writing :)
     
  6. RomuloFerreira

    RomuloFerreira

    Joined:
    Apr 22, 2014
    Posts:
    2
    This is really awesome, thank you :D
     
  7. Smidgens

    Smidgens

    Joined:
    Nov 2, 2014
    Posts:
    25
    5.6.0. Works like a charm, and just saved me hours of work aligning everything correctly. Cheers!
     
  8. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    487
    I would also add:

    Code (csharp):
    1. Undo.RecordObject(r, "Set anchors around object");
    under line 13 so that undo/redo works and Unity also recognises that the scene is dirty!
     
  9. Azes923

    Azes923

    Joined:
    Jun 7, 2017
    Posts:
    2
    Works perfectly with Unity 2017 3.03f! Thanks for the awesome script!
     
  10. sjakur

    sjakur

    Joined:
    Apr 24, 2016
    Posts:
    4
    omg i love you!!
     
  11. Xevetor

    Xevetor

    Joined:
    Oct 14, 2017
    Posts:
    3
    can't believe there's still no default
     
  12. gamefish

    gamefish

    Joined:
    Jul 5, 2013
    Posts:
    14
    Great code, but how should I modify the code to let the sub UI element preserve it's size or ratio when screen size changed?
     
  13. gamefish

    gamefish

    Joined:
    Jul 5, 2013
    Posts:
    14
    This looks nasty but it works for my needs, just change
    Code (CSharp):
    1. r.anchorMin = anchorMin;
    2. r.anchorMax = anchorMax;
    3.  
    4. r.offsetMin = new Vector2(0, 0);
    5. r.offsetMax = new Vector2(1, 1);
    to:

    Code (CSharp):
    1. r.anchorMin = (anchorMin+anchorMax)/2;
    2. r.anchorMax = (anchorMin+anchorMax)/2;
    3.  
    4. Vector2 objSize = r.offsetMax-r.offsetMin;
    5. r.offsetMin = -objSize/2;
    6. r.offsetMax = objSize/2;
    you can preserve element aspect ratio
     
    Last edited: Apr 16, 2018
    ProGameDevUser likes this.
  14. gillemp

    gillemp

    Joined:
    Nov 23, 2015
    Posts:
    81
    Great work!

    However, I would change the line "r.offsetMax = new Vector2(1, 1);" to "r.offsetMax = new Vector2(0, 0);"
     
  15. Lapsapnow

    Lapsapnow

    Joined:
    Jul 4, 2019
    Posts:
    51
    7 years later. Still a wonderful script that I am infuriated Unity doesn't have by default.
     
    TheFastLane likes this.
  16. yehudaKarasenty

    yehudaKarasenty

    Joined:
    Jan 9, 2019
    Posts:
    3
    Thanksss!!!!!!!!:))
     
  17. unity3dcx

    unity3dcx

    Joined:
    Sep 10, 2019
    Posts:
    2
    Man You just save my time Thanks <3
     
  18. MSOTech

    MSOTech

    Joined:
    Oct 12, 2013
    Posts:
    3
    I made it work with multiple selections and made edits suggested by others in the comments. The final version seems to work great.

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. public class AnchorSnapper : MonoBehaviour
    5. {
    6.     [MenuItem ("UI/Snap Anchor Around Object")]
    7.     static void uGUIAnchorAroundObject()
    8.     {
    9.         var oList = Selection.gameObjects;
    10.         for (int i = 0; i < oList.Length; i++)
    11.         {
    12.             var o = oList[i];
    13.             if (o != null && o.GetComponent<RectTransform>() != null)
    14.             {
    15.                 var r = o.GetComponent<RectTransform>();
    16.                 Undo.RecordObject(r, "Set anchors around object");
    17.                 var p = o.transform.parent.GetComponent<RectTransform>();
    18.        
    19.                 var offsetMin = r.offsetMin;
    20.                 var offsetMax = r.offsetMax;
    21.                 var _anchorMin = r.anchorMin;
    22.                 var _anchorMax = r.anchorMax;
    23.        
    24.                 var parent_width = p.rect.width;  
    25.                 var parent_height = p.rect.height;
    26.        
    27.                 var anchorMin = new Vector2(_anchorMin.x + (offsetMin.x / parent_width),
    28.                     _anchorMin.y + (offsetMin.y / parent_height));
    29.                 var anchorMax = new Vector2(_anchorMax.x + (offsetMax.x / parent_width),
    30.                     _anchorMax.y + (offsetMax.y / parent_height));
    31.        
    32.                 r.anchorMin = anchorMin;
    33.                 r.anchorMax = anchorMax;
    34.              
    35.                 r.offsetMin = new Vector2(0, 0);
    36.                 r.offsetMax = new Vector2(0, 0);
    37.              
    38.                 r.pivot = new Vector2(0.5f, 0.5f);
    39.             }
    40.         }
    41.     }
    42. }
     
    ProGameDevUser likes this.
  19. Troutmonkey

    Troutmonkey

    Joined:
    Jun 11, 2014
    Posts:
    7
    You can also add
    MenuItem("CONTEXT/RectTransform/Anchor Current Position")]
    to add a context menu to right click. Honest I can't imagine doing it via the Menu item as that seems tedious.
    I've also added another function to Fill Parent which is another common task.
    Script doesn't need to be a monobehaviour either
    Code (CSharp):
    1.  
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5.     public class RectTransformSnapAnchors
    6.     {
    7.         [MenuItem("Tools/UI/Anchor Around Object")]
    8.         [MenuItem("CONTEXT/RectTransform/Anchor Current Position")]
    9.         static void uGUIAnchorAroundObject()
    10.         {
    11.             foreach (GameObject o in Selection.gameObjects)
    12.             {
    13.                 if (o == null)
    14.                 {
    15.                     return;
    16.                 }
    17.  
    18.                 var r = o.GetComponent<RectTransform>();
    19.  
    20.                 if (r == null || r.parent == null)
    21.                 {
    22.                     continue;
    23.                 }
    24.  
    25.                 Undo.RecordObject(o, "SnapAnchors");
    26.                 AnchorRect(r);
    27.             }
    28.         }
    29.  
    30.         static void AnchorRect(RectTransform r)
    31.         {
    32.             var p = r.parent.GetComponent<RectTransform>();
    33.  
    34.             var offsetMin = r.offsetMin;
    35.             var offsetMax = r.offsetMax;
    36.             var _anchorMin = r.anchorMin;
    37.             var _anchorMax = r.anchorMax;
    38.  
    39.             var parent_width = p.rect.width;
    40.             var parent_height = p.rect.height;
    41.  
    42.             var anchorMin = new Vector2(_anchorMin.x + (offsetMin.x / parent_width),
    43.                                         _anchorMin.y + (offsetMin.y / parent_height));
    44.             var anchorMax = new Vector2(_anchorMax.x + (offsetMax.x / parent_width),
    45.                                         _anchorMax.y + (offsetMax.y / parent_height));
    46.  
    47.             r.anchorMin = anchorMin;
    48.             r.anchorMax = anchorMax;
    49.  
    50.             r.offsetMin = new Vector2(0, 0);
    51.             r.offsetMax = new Vector2(0, 0);
    52.             r.pivot = new Vector2(0.5f, 0.5f);
    53.         }
    54.  
    55.         [MenuItem("CONTEXT/RectTransform/Fill Parent")]
    56.         static void FillParent()
    57.         {
    58.             RectTransform rect = Selection.activeTransform.GetComponent<RectTransform>();
    59.  
    60.             rect.anchorMin = Vector2.zero;
    61.             rect.anchorMax = Vector2.one;
    62.             rect.sizeDelta = Vector2.zero;
    63.         }
    64.     }
    65.  
    [/ICODE]
     
  20. ProGameDevUser

    ProGameDevUser

    Joined:
    Mar 17, 2018
    Posts:
    115
    Thank man!!! This scripts is very good!!!