Search Unity

Hierarchy Selection - Select first child of selection, and expand/collapse selection

Discussion in 'Editor & General Support' started by Zan_Kievit, Feb 16, 2021.

  1. Zan_Kievit

    Zan_Kievit

    Joined:
    Mar 24, 2018
    Posts:
    14
    I've always had a lot of annoyances in the hierarchy with tedious busywork of things like for example changing fonts on buttons or having to expand/collapse a bunch of things.

    So I finally made a little tool to try and solve these problems and thought I'd share it.
    Currently, the tool can:
    - Select the first child of your selection
    - Expand/Collapse your selection
    This can be done with a right-click on the selection. Add this script to any folder to your project named "Editor" for it to work. Enjoy clicking a bit less!

    Feel free to expand the tool if you see any features or improvements to add and post it here!
    Code (CSharp):
    1. /*===================== Hierarchy Selection =====================
    2. A hierarchy selection tool that, with a simple right-click can: select the first child of the selection, and expand/collapse the selection (Aka: fold/unfold.)
    3. Made by Zan Kievit
    4. =============================================================*/
    5. using System.Collections.Generic;
    6. using System;
    7. using System.Reflection;
    8. using UnityEngine;
    9. using UnityEditor;
    10.  
    11. namespace ZanKievit.EditorOnly
    12. {
    13.     static class HierarchySelection
    14.     {
    15.         static bool runSelectChildren = true;
    16.  
    17.         /// <summary>
    18.         /// Selects the first child of every selected object.
    19.         /// </summary>
    20.         [MenuItem("GameObject/Select First Child", false, -1000)]
    21.         public static void SelectChildren ()
    22.         {
    23.             if (runSelectChildren) // Prevents function from being executed twice
    24.             {
    25.                 //Expand current selection to show the children you're about to select
    26.                 foreach (var obj in Selection.gameObjects)
    27.                 {
    28.                     SetExpanded(obj, true);
    29.                 }
    30.  
    31.                 //Select every first child
    32.                 List<GameObject> objects = new List<GameObject>();
    33.  
    34.                 for (int i = 0; i < Selection.gameObjects.Length; i++)
    35.                 {
    36.                     var obj = Selection.gameObjects[i].transform;
    37.  
    38.                     if (obj.childCount > 0)
    39.                         objects.Add(obj.GetChild(0).gameObject);
    40.                 }
    41.                 Selection.objects = objects.ToArray();
    42.             }
    43.             runSelectChildren = false;
    44.         }
    45.  
    46.         /// <summary>
    47.         /// Disables the "Select First Child" button if the currently selected objects have no children to select
    48.         /// </summary>
    49.         [MenuItem("GameObject/Select First Child", true)]
    50.         public static bool ValidateSelectChildren()
    51.         {
    52.             runSelectChildren = true;
    53.             return SelectionHasChildren();
    54.         }
    55.  
    56.         /// <summary>
    57.         /// Collapses the selected objects
    58.         /// </summary>
    59.         [MenuItem("GameObject/Collapse Selection", false, -800)]
    60.         public static void CollapseSelection ()
    61.         {
    62.             if (runSelectChildren) // Prevents function from being executed twice
    63.             {
    64.                 foreach (var obj in Selection.gameObjects)
    65.                 {
    66.                     SetExpanded(obj, false);
    67.                 }
    68.             }
    69.             runSelectChildren = false;
    70.         }
    71.  
    72.         /// <summary>
    73.         /// Disables the "Collapse Selection" button if the currently selected objects have nothing to collapse
    74.         /// </summary>
    75.         [MenuItem("GameObject/Collapse Selection", true)]
    76.         public static bool ValidateCollapseSelection ()
    77.         {
    78.             runSelectChildren = true;
    79.             return SelectionHasChildren();
    80.         }
    81.  
    82.         /// <summary>
    83.         /// Expands the selected objects
    84.         /// </summary>
    85.         [MenuItem("GameObject/Expand Selection", false, -800)]
    86.         public static void ExpandSelection ()
    87.         {
    88.             if (runSelectChildren) // Prevents function from being executed twice
    89.             {
    90.                 foreach (var obj in Selection.gameObjects)
    91.                 {
    92.                     SetExpanded(obj, true);
    93.                 }
    94.             }
    95.             runSelectChildren = false;
    96.         }
    97.  
    98.         /// <summary>
    99.         /// Disables the "Expand Selection" button if the currently selected objects have nothing to expand
    100.         /// </summary>
    101.         [MenuItem("GameObject/Expand Selection", true)]
    102.         public static bool ValidateExpandSelection ()
    103.         {
    104.             runSelectChildren = true;
    105.             return SelectionHasChildren();
    106.         }
    107.  
    108.         /// <summary>
    109.         /// Checks if any of the selected gameobjects in the Hierarchy have children
    110.         /// </summary>
    111.         static bool SelectionHasChildren()
    112.         {
    113.             foreach (var obj in Selection.gameObjects)
    114.             {
    115.                 if (obj.transform.childCount > 0)
    116.                     return true;
    117.             }
    118.             return false;
    119.         }
    120.  
    121.         /// <summary>
    122.         /// Expand or collapse object in Hierarchy recursively
    123.         /// </summary>
    124.         /// <param name="obj">The object to expand or collapse</param>
    125.         /// <param name="expand">A boolean to indicate if you want to expand or collapse the object</param>
    126.         public static void SetExpandedRecursive (GameObject obj, bool expand)
    127.         {
    128.             var methodInfo = GetHierarchyWindowType().GetMethod("SetExpandedRecursive");
    129.  
    130.             methodInfo.Invoke(GetHierarchyWindow(), new object[] { obj.GetInstanceID(), expand });
    131.         }
    132.  
    133.         /// <summary>
    134.         ///  Expand or collapse object in Hierarchy
    135.         /// </summary>
    136.         /// <param name="obj">The object to expand or collapse</param>
    137.         /// <param name="expand">A boolean to indicate if you want to expand or collapse the object</param>
    138.         public static void SetExpanded (GameObject obj, bool expand)
    139.         {
    140.             object sceneHierarchy = GetHierarchyWindowType().GetProperty("sceneHierarchy").GetValue(GetHierarchyWindow());
    141.             var methodInfo = sceneHierarchy.GetType().GetMethod("ExpandTreeViewItem", BindingFlags.NonPublic | BindingFlags.Instance);
    142.  
    143.             methodInfo.Invoke(sceneHierarchy, new object[] { obj.GetInstanceID(), expand });
    144.         }
    145.  
    146.         static Type GetHierarchyWindowType()
    147.         {
    148.             return typeof(EditorWindow).Assembly.GetType("UnityEditor.SceneHierarchyWindow");
    149.         }
    150.  
    151.         static EditorWindow GetHierarchyWindow ()
    152.         {
    153.             EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
    154.             return EditorWindow.focusedWindow;
    155.         }
    156.     }
    157. }
     
  2. vizgl

    vizgl

    Joined:
    Nov 4, 2014
    Posts:
    61
    Thank you, bro.
     
    Zan_Kievit and YOK-ARTIK like this.