Search Unity

How to multi-select scene hierarchy objects in code

Discussion in 'Scripting' started by T0rp3d0, Apr 4, 2020.

  1. T0rp3d0

    T0rp3d0

    Joined:
    Feb 4, 2018
    Posts:
    31
    Hello, I've been trying and failed to use the Selection class to multi-select some objects in the scene hierarchy -similar to how you would by holding down Ctrl and clicking on all the objects you want selected. Does anyone have suggestions or ideas to achieve something similar? I have a list and a serialized bool property in my Monobehaviour. When i toggle the bool, the items in the list -which are also objects in the scene, should all be selected.

    Thank you.
     
    mrbarana2005 likes this.
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
  3. T0rp3d0

    T0rp3d0

    Joined:
    Feb 4, 2018
    Posts:
    31
    Yes it is strictly an Editor Utility, not meant for during play mode.
    Unfortunately i've tried all the Selection class methods, but none give me the type of Ctrl+MouseClick multi-select that i want.
    By using Ctrl+MouseClick, the inspector window has dashed lines in certain fields, and i can edit some field for all the selected objects at once.
    These snapshots show what i mean. Do you have any other suggestions?
     

    Attached Files:

  4. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Let me make sure I understand. You want to execute some code in a script that causes some number of game object in the Hierarchy view to become selected, as though you had ctrl-clicked each one individually?
     
  5. T0rp3d0

    T0rp3d0

    Joined:
    Feb 4, 2018
    Posts:
    31
    That is correct
     
  6. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    It seems to work fine for me. Here's a simple script that selects Rigidbodies in the scene. After I click the button, all gameObjects with a Rigidbody become selected in the Hierarchy view, and I can multi-edit the Rigidbodies in the inspector:

    upload_2020-4-5_10-18-45.png

    Here's the script:

    Code (CSharp):
    1. using System.Linq;
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. namespace GraviaSoftware.Gravia.Editor
    6. {
    7.  
    8.     public class SelectObjects : EditorWindow
    9.     {
    10.  
    11.         [MenuItem("Window/Select Objects")]
    12.         static void Init()
    13.         {
    14.             // Get existing open window or if none, make a new one:
    15.             SelectObjects window = (SelectObjects)EditorWindow.GetWindow(typeof(SelectObjects));
    16.             window.Show();
    17.         }
    18.  
    19.         void OnGUI()
    20.         {
    21.             if (GUILayout.Button("Select Rigidbodies"))
    22.             {
    23.                 // Find all game objects with Rigidbodies on them.
    24.                 Selection.objects = GameObject.FindObjectsOfType<Rigidbody>().Select(rb => rb.gameObject).ToArray();
    25.             }
    26.         }
    27.     }
    28. }
    29.  
     
    LuLusg and T0rp3d0 like this.
  7. T0rp3d0

    T0rp3d0

    Joined:
    Feb 4, 2018
    Posts:
    31
    Okay its works halfway now -all objects are selected as evidenced by them "sharing" the same inspector window.
    My mistake was in looping the "pre-assembled" list (property), to add each object therein to the Selection.object array.
    The remaining half to the problem is that there still is no highlighting in the hierarchy view, but i can live with that.

    This will speed up my workflow considerably.

    Thank you dearly.
     
  8. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    In the screenshot I posted, that code was causing the objects to be selected/highlighted in blue in the Hierarchy window. Is that not happening for you?
     
  9. T0rp3d0

    T0rp3d0

    Joined:
    Feb 4, 2018
    Posts:
    31
    No highlighting occurs, only sharing of the inspector window (as seen to the right of your screenshot).
     
  10. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    That's odd. What version of Unity are you using? I didn't do anything special to get the highlighting to work.
     
  11. T0rp3d0

    T0rp3d0

    Joined:
    Feb 4, 2018
    Posts:
    31
    I use the latest version -2019.3.7f1. Maybe worth noting is that i often run into a bug where clicking on an object in the hierarchy is unresponsive -as in the inspector doesn't change, nor does the object highlight :(
     
  12. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    I just tried in 2019.3.7, and it works fine for me:

    upload_2020-4-5_16-38-16.png

    Not sure what kind of selection trouble you're running into in general. Do you have any other code in your project that messed with Selection that might be getting called unintentionally? Maybe see if this works in a brand new project?
     
  13. T0rp3d0

    T0rp3d0

    Joined:
    Feb 4, 2018
    Posts:
    31
    I should have told you earlier that i was using your logic within the OnInspectorGUI() callback of an editor (CustomEditor) script.
    Starting a new project did unfortunately not solve the problem. Although, your exact code called from within OnGUI() does work perfectly.
    Which means the problem is in calling from OnInspectorGUI().
    Here's my code:

    Code (CSharp):
    1. public abstract class GenericConfigJointsList_Editor<T> : Editor
    2.         where T : ConfigurableJoints
    3.     {
    4.         private T _configJoints;
    5.  
    6.         private void OnEnable()
    7.         {
    8.             if ( target == null ) return;
    9.                                
    10.             _configJoints = target as T;
    11.         }
    12.  
    13.         public override void OnInspectorGUI()
    14.         {
    15.             DrawDefaultInspector();
    16.  
    17.             GUILayout.Space(10f);
    18.            
    19.             if (GUILayout.Button("Select All Joints", GUILayout.Height(_lineHeightSpace)))
    20.             {
    21.                 Selection.objects = _configJoints.Joints.ToArray();
    22.             }
    23.            
    24.             GUILayout.Space(10f);
    25.                              
    26.          }
    27.     }
     
  14. T0rp3d0

    T0rp3d0

    Joined:
    Feb 4, 2018
    Posts:
    31
    I managed to get it working with the help of @d
    Code (CSharp):
    1. if (GUILayout.Button("Select All Joints", GUILayout.Height(_lineHeightSpace)))
    2. {
    3.     // Find all game objects with ConfigurableJoints on them.
    4.     GameObject[] confJoints = GameObject.FindObjectsOfType<ConfigurableJoint>().Select(rb => rb.gameObject).ToArray();
    5.                
    6.     IEnumerable<GameObject> activeConfJoints = confJoints.Where(j => j.activeInHierarchy && j.name.Contains(_charJoints.SelectionSearchSubString));
    7.                                
    8.     Selection.objects = activeConfJoints.ToArray();
    9. }
    goyette for those interested:
     
    mrwellmann and Nit_Ram like this.