Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[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:
    24
    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:
    2
    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:
    114
    Thank man!!! This scripts is very good!!!