Page 1 sur 1

Séparateur dans la hierarchie

Publié : 21 Jan 2020 12:21
par Bouiss
Salut braves gens !

Je partage avec vous un petit script pour créer des objets vides qui servent de séparateurs dans la fenêtre hierarchy.
Ce script ne changera pas la face du monde mais si comme moi vous avez du mal à y voir clair dans votre hiérarchie et que vous n'avez pas de plugins dédiés, cela pourrait vous servir.

La partie du script sur la création de layer et de tags est une copie du script de DubiDubini : https://forum.unity.com/threads/create- ... st-4882691

Code : Tout sélectionner

using UnityEngine;
using UnityEditor;
using System.Collections;

class HierarchySeparatorEditor : EditorWindow 
{
    string separatorName="";
    static GameObject separator;
    string prefix = "";
    int prefixSize = 0;
    int maxCount = 36;
    private static int maxLayers = 31;
    private static int maxTags = 10000;


#if UNITY_EDITOR
    [MenuItem("GameObject/**Helpers**/Separator", false, 10)]
    static void Init()
    {
        var window = GetWindow<HierarchySeparatorEditor>();
        window.Show();
    }
#endif

    void OnGUI()
    {
        EditorGUI.DropShadowLabel(new Rect(0, 0, position.width, 30),"Rename the selector");

        separatorName = EditorGUI.TextField(new Rect(0, 45, position.width -10, 20)," Separator name :",separatorName);

        if (GUI.Button(new Rect((position.width/2)-50, 80, 100, 30), " Valider"))
        {
            CreateSeparator();
            this.Close();
        }   
    }
 
    void OnInspectorUpdate()
    {
        Repaint();
    }

    /// <summary>
    /// Create a separator with tag and layer
    /// </summary>
    public void CreateSeparator()
    {
        prefixSize = ((maxCount - separatorName.Length) / 2);

        if (separatorName.Length < 1)
        {
            prefix = new string('=', prefixSize + 1);
            separator = new GameObject($"{prefix}{separatorName}{prefix}");
        }
        else
        {
            prefix = new string('=', prefixSize);
            separator = new GameObject($"{prefix} {separatorName} {prefix}");
        }
        NewLayer("ignoreOnRunTime");
        separator.layer = LayerMask.NameToLayer("ignoreOnRunTime");
        separator.tag = NewTag("Helpers");
        separator.SetActive(false);
    }

    // This following script is from DubiDuboni : https://forum.unity.com/threads/create-tags-and-layers-in-the-editor-using-script-both-edit-and-runtime-modes.732119/#post-4882691

    /// <summary>
    /// Adds the tag.
    /// </summary>
    /// <returns><c>true</c>, if tag was added, <c>false</c> otherwise.</returns>
    /// <param name="tagName">Tag name.</param>
    public static bool CreateTag(string tagName)
    {
        // Open tag manager
        SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
        // Tags Property
        SerializedProperty tagsProp = tagManager.FindProperty("tags");
        if (tagsProp.arraySize >= maxTags)
        {
            Debug.Log("No more tags can be added to the Tags property. You have " + tagsProp.arraySize + " tags");
            return false;
        }
        // if not found, add it
        if (!PropertyExists(tagsProp, 0, tagsProp.arraySize, tagName))
        {
            int index = tagsProp.arraySize;
            // Insert new array element
            tagsProp.InsertArrayElementAtIndex(index);
            SerializedProperty sp = tagsProp.GetArrayElementAtIndex(index);
            // Set array element to tagName
            sp.stringValue = tagName;
            Debug.Log("Tag: " + tagName + " has been added");
            // Save settings
            tagManager.ApplyModifiedProperties();

            return true;
        }
        else
        {
            //Debug.Log ("Tag: " + tagName + " already exists");
        }
        return false;
    }

    public static string NewTag(string name)
    {
        CreateTag(name);

        if (name == null || name == "")
        {
            name = "Untagged";
        }

        return name;
    }

    /// <summary>
    /// Checks if the value exists in the property.
    /// </summary>
    /// <returns><c>true</c>, if exists was propertyed, <c>false</c> otherwise.</returns>
    /// <param name="property">Property.</param>
    /// <param name="start">Start.</param>
    /// <param name="end">End.</param>
    /// <param name="value">Value.</param>
    private static bool PropertyExists(SerializedProperty property, int start, int end, string value)
    {
        for (int i = start; i < end; i++)
        {
            SerializedProperty t = property.GetArrayElementAtIndex(i);
            if (t.stringValue.Equals(value))
            {
                return true;
            }
        }
        return false;
    }

    /// <summary>
    /// Adds the layer.
    /// </summary>
    /// <returns><c>true</c>, if layer was added, <c>false</c> otherwise.</returns>
    /// <param name="layerName">Layer name.</param>
    public static bool CreateLayer(string layerName)
    {
        // Open tag manager
        SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
        // Layers Property
        SerializedProperty layersProp = tagManager.FindProperty("layers");
        if (!PropertyExists(layersProp, 0, maxLayers, layerName))
        {
            SerializedProperty sp;
            // Start at layer 9th index -> 8 (zero based) => first 8 reserved for unity / greyed out
            for (int i = 8, j = maxLayers; i < j; i++)
            {
                sp = layersProp.GetArrayElementAtIndex(i);
                if (sp.stringValue == "")
                {
                    // Assign string value to layer
                    sp.stringValue = layerName;
                    Debug.Log("Layer: " + layerName + " has been added");
                    // Save settings
                    tagManager.ApplyModifiedProperties();
                    return true;
                }
                if (i == j)
                    Debug.Log("All allowed layers have been filled");
            }
        }
        else
        {
            //Debug.Log ("Layer: " + layerName + " already exists");
        }
        return false;
    }

    public static string NewLayer(string name)
    {
        if (name != null || name != "")
        {
            CreateLayer(name);
        }

        return name;
    }

}
Pour l'utiliser, vous faites un clic droit dans la hierarchie puis **Herlpers**/Separator et voilà.

[EDIT] Je rajoute une version modifiée avec de la couleur pour ceux que ça intéresse. Merci Max pour le lien

Code : Tout sélectionner

using UnityEngine;
using UnityEditor;
using System.Collections;

[InitializeOnLoad]
class HierarchySeparatorEditor : EditorWindow 
{
    string separatorName="";
    static GameObject separator;
    string prefix = "";
    int prefixSize = 0;
    int maxCount = 36;
    private static int maxLayers = 31;
    private static int maxTags = 10000;


    static HierarchySeparatorEditor()
    {
        EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
    }

    static void HierarchyWindowItemOnGUI(int instanceID, Rect selectionRect)
    {
        var gameObject = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
        if (gameObject != null && gameObject.name.StartsWith("==", System.StringComparison.Ordinal))
        {
            Color col = new Color32(194,150,194,255);
            EditorGUI.DrawRect(selectionRect, col);
            EditorGUI.LabelField(selectionRect, gameObject.name.ToUpperInvariant());
        }
    }

#if UNITY_EDITOR
    [MenuItem("GameObject/**Helpers**/Separator", false, 10)]
    static void Init()
    {
        var window = GetWindow<HierarchySeparatorEditor>();
        window.Show();

    }
#endif

    void OnGUI()
    {
        EditorGUI.DropShadowLabel(new Rect(0, 0, position.width, 30),"Rename the selector");

        separatorName = EditorGUI.TextField(new Rect(0, 45, position.width -10, 20)," Separator name :",separatorName);

        if (GUI.Button(new Rect((position.width/2)-50, 80, 100, 30), " Valider"))
        {
            CreateSeparator();
            this.Close();
        }   
    }
 
    void OnInspectorUpdate()
    {
        Repaint();
    }

    /// <summary>
    /// Create a separator with tag and layer
    /// </summary>
    public void CreateSeparator()
    {
        prefixSize = ((maxCount - separatorName.Length) / 2);

        if (separatorName.Length < 1)
        {
            prefix = new string('=', prefixSize + 1);
            separator = new GameObject($"{prefix}{separatorName}{prefix}");
        }
        else
        {
            prefix = new string('=', prefixSize);
            separator = new GameObject($"{prefix} {separatorName} {prefix}");
        }

        NewLayer("ignoreOnRunTime");
        separator.layer = LayerMask.NameToLayer("ignoreOnRunTime");
        separator.tag = NewTag("Helpers");
        separator.SetActive(false);
    }

    // This following script is from DubiDuboni : https://forum.unity.com/threads/create-tags-and-layers-in-the-editor-using-script-both-edit-and-runtime-modes.732119/#post-4882691

    /// <summary>
    /// Adds the tag.
    /// </summary>
    /// <returns><c>true</c>, if tag was added, <c>false</c> otherwise.</returns>
    /// <param name="tagName">Tag name.</param>
    public static bool CreateTag(string tagName)
    {
        // Open tag manager
        SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
        // Tags Property
        SerializedProperty tagsProp = tagManager.FindProperty("tags");
        if (tagsProp.arraySize >= maxTags)
        {
            Debug.Log("No more tags can be added to the Tags property. You have " + tagsProp.arraySize + " tags");
            return false;
        }
        // if not found, add it
        if (!PropertyExists(tagsProp, 0, tagsProp.arraySize, tagName))
        {
            int index = tagsProp.arraySize;
            // Insert new array element
            tagsProp.InsertArrayElementAtIndex(index);
            SerializedProperty sp = tagsProp.GetArrayElementAtIndex(index);
            // Set array element to tagName
            sp.stringValue = tagName;
            Debug.Log("Tag: " + tagName + " has been added");
            // Save settings
            tagManager.ApplyModifiedProperties();

            return true;
        }
        else
        {
            //Debug.Log ("Tag: " + tagName + " already exists");
        }
        return false;
    }

    public static string NewTag(string name)
    {
        CreateTag(name);

        if (name == null || name == "")
        {
            name = "Untagged";
        }

        return name;
    }

    /// <summary>
    /// Checks if the value exists in the property.
    /// </summary>
    /// <returns><c>true</c>, if exists was propertyed, <c>false</c> otherwise.</returns>
    /// <param name="property">Property.</param>
    /// <param name="start">Start.</param>
    /// <param name="end">End.</param>
    /// <param name="value">Value.</param>
    private static bool PropertyExists(SerializedProperty property, int start, int end, string value)
    {
        for (int i = start; i < end; i++)
        {
            SerializedProperty t = property.GetArrayElementAtIndex(i);
            if (t.stringValue.Equals(value))
            {
                return true;
            }
        }
        return false;
    }

    /// <summary>
    /// Adds the layer.
    /// </summary>
    /// <returns><c>true</c>, if layer was added, <c>false</c> otherwise.</returns>
    /// <param name="layerName">Layer name.</param>
    public static bool CreateLayer(string layerName)
    {
        // Open tag manager
        SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
        // Layers Property
        SerializedProperty layersProp = tagManager.FindProperty("layers");
        if (!PropertyExists(layersProp, 0, maxLayers, layerName))
        {
            SerializedProperty sp;
            // Start at layer 9th index -> 8 (zero based) => first 8 reserved for unity / greyed out
            for (int i = 8, j = maxLayers; i < j; i++)
            {
                sp = layersProp.GetArrayElementAtIndex(i);
                if (sp.stringValue == "")
                {
                    // Assign string value to layer
                    sp.stringValue = layerName;
                    Debug.Log("Layer: " + layerName + " has been added");
                    // Save settings
                    tagManager.ApplyModifiedProperties();
                    return true;
                }
                if (i == j)
                    Debug.Log("All allowed layers have been filled");
            }
        }
        else
        {
            //Debug.Log ("Layer: " + layerName + " already exists");
        }
        return false;
    }

    public static string NewLayer(string name)
    {
        if (name != null || name != "")
        {
            CreateLayer(name);
        }

        return name;
    }

}

Re: Séparateur dans la hierarchie

Publié : 21 Jan 2020 12:58
par Max
Salut, et merci pour le partage :super:

Cela rejoint dans l'esprit ce sujet de la section TIPs: viewtopic.php?f=98&t=16952

Re: Séparateur dans la hierarchie

Publié : 21 Jan 2020 13:32
par Bouiss
Max a écrit :
21 Jan 2020 12:58
Salut, et merci pour le partage :super:

Cela rejoint dans l'esprit ce sujet de la section TIPs: viewtopic.php?f=98&t=16952
Ha mais je ne l'avais pas vu celui là ! c'est exactement l'idée que j'avais au départ. Merci bien