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

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

using UnityEditor;
using UnityEngine;
using System.Collections;

public class UGUIMenu : MonoBehaviour
{
    [MenuItem ("UI/Anchor Around Object")]
    static void uGUIAnchorAroundObject()
    {
        var o = Selection.activeGameObject;
        if (o != null && o.GetComponent<RectTransform>() != null)
        {
            var r = o.GetComponent<RectTransform>();
            var p = o.transform.parent.GetComponent<RectTransform>();
           
            var offsetMin = r.offsetMin;
            var offsetMax = r.offsetMax;
            var _anchorMin = r.anchorMin;
            var _anchorMax = r.anchorMax;
           
            var parent_width = p.rect.width;       
            var parent_height = p.rect.height;   
           
            var anchorMin = new Vector2(_anchorMin.x + (offsetMin.x / parent_width),
                                        _anchorMin.y + (offsetMin.y / parent_height));
            var anchorMax = new Vector2(_anchorMax.x + (offsetMax.x / parent_width),
                                        _anchorMax.y + (offsetMax.y / parent_height));
           
            r.anchorMin = anchorMin;
            r.anchorMax = anchorMax;
           
            r.offsetMin = new Vector2(0, 0);
            r.offsetMax = new Vector2(1, 1);
            r.pivot = new Vector2(0.5f, 0.5f);
           
        }
    }
}


13 Likes

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 .

6 Likes

Awesome! Thank you so much to both of you! This is going to save me lots of time adjusting anchors!

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 :slight_smile:

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 :slight_smile:

This is really awesome, thank you :smile:

5.6.0. Works like a charm, and just saved me hours of work aligning everything correctly. Cheers!

I would also add:

Undo.RecordObject(r, "Set anchors around object");

under line 13 so that undo/redo works and Unity also recognises that the scene is dirty!

3 Likes

Works perfectly with Unity 2017 3.03f! Thanks for the awesome script!

omg i love you!!

can’t believe there’s still no default

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?

This looks nasty but it works for my needs, just change

r.anchorMin = anchorMin;
r.anchorMax = anchorMax;

r.offsetMin = new Vector2(0, 0);
r.offsetMax = new Vector2(1, 1);

to:

r.anchorMin = (anchorMin+anchorMax)/2;
r.anchorMax = (anchorMin+anchorMax)/2;

Vector2 objSize = r.offsetMax-r.offsetMin;
r.offsetMin = -objSize/2;
r.offsetMax = objSize/2;

you can preserve element aspect ratio

1 Like

Great work!

However, I would change the line “r.offsetMax = new Vector2(1, 1);” to “r.offsetMax = new Vector2(0, 0);”

7 years later. Still a wonderful script that I am infuriated Unity doesn’t have by default.

1 Like

Thanksss!!!:))

Man You just save my time Thanks <3

I made it work with multiple selections and made edits suggested by others in the comments. The final version seems to work great.

using UnityEditor;
using UnityEngine;

public class AnchorSnapper : MonoBehaviour
{
    [MenuItem ("UI/Snap Anchor Around Object")]
    static void uGUIAnchorAroundObject()
    {
        var oList = Selection.gameObjects;
        for (int i = 0; i < oList.Length; i++)
        {
            var o = oList[i];
            if (o != null && o.GetComponent<RectTransform>() != null)
            {
                var r = o.GetComponent<RectTransform>();
                Undo.RecordObject(r, "Set anchors around object");
                var p = o.transform.parent.GetComponent<RectTransform>();
        
                var offsetMin = r.offsetMin;
                var offsetMax = r.offsetMax;
                var _anchorMin = r.anchorMin;
                var _anchorMax = r.anchorMax;
        
                var parent_width = p.rect.width;   
                var parent_height = p.rect.height;
        
                var anchorMin = new Vector2(_anchorMin.x + (offsetMin.x / parent_width),
                    _anchorMin.y + (offsetMin.y / parent_height));
                var anchorMax = new Vector2(_anchorMax.x + (offsetMax.x / parent_width),
                    _anchorMax.y + (offsetMax.y / parent_height));
        
                r.anchorMin = anchorMin;
                r.anchorMax = anchorMax;
             
                r.offsetMin = new Vector2(0, 0);
                r.offsetMax = new Vector2(0, 0);
             
                r.pivot = new Vector2(0.5f, 0.5f);
            }
        }
    }
}
1 Like

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

using UnityEditor;
using UnityEngine;

    public class RectTransformSnapAnchors
    {
        [MenuItem("Tools/UI/Anchor Around Object")]
        [MenuItem("CONTEXT/RectTransform/Anchor Current Position")]
        static void uGUIAnchorAroundObject()
        {
            foreach (GameObject o in Selection.gameObjects)
            {
                if (o == null)
                {
                    return;
                }

                var r = o.GetComponent<RectTransform>();

                if (r == null || r.parent == null)
                {
                    continue;
                }

                Undo.RecordObject(o, "SnapAnchors");
                AnchorRect(r);
            }
        }

        static void AnchorRect(RectTransform r)
        {
            var p = r.parent.GetComponent<RectTransform>();

            var offsetMin = r.offsetMin;
            var offsetMax = r.offsetMax;
            var _anchorMin = r.anchorMin;
            var _anchorMax = r.anchorMax;

            var parent_width = p.rect.width;
            var parent_height = p.rect.height;

            var anchorMin = new Vector2(_anchorMin.x + (offsetMin.x / parent_width),
                                        _anchorMin.y + (offsetMin.y / parent_height));
            var anchorMax = new Vector2(_anchorMax.x + (offsetMax.x / parent_width),
                                        _anchorMax.y + (offsetMax.y / parent_height));

            r.anchorMin = anchorMin;
            r.anchorMax = anchorMax;

            r.offsetMin = new Vector2(0, 0);
            r.offsetMax = new Vector2(0, 0);
            r.pivot = new Vector2(0.5f, 0.5f);
        }

        [MenuItem("CONTEXT/RectTransform/Fill Parent")]
        static void FillParent()
        {
            RectTransform rect = Selection.activeTransform.GetComponent<RectTransform>();

            rect.anchorMin = Vector2.zero;
            rect.anchorMax = Vector2.one;
            rect.sizeDelta = Vector2.zero;
        }
    }

[/ICODE]

3 Likes

Thank man!!! This scripts is very good!!!