How to multi-select scene hierarchy objects in code

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.

1 Like

I assume you’re strictly talking about creating an Editor utility, and that you’re not selecting objects while the game is actually playing?

This link appears to show how you can perform multi-select in the editor:

You essentially just assign the objects to `Selection.objects

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?

5672149--591241--Multiple Select.PNG
5672149--591244--Multiple Select2.PNG

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?

That is correct

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:

Here’s the script:

using System.Linq;
using UnityEditor;
using UnityEngine;

namespace GraviaSoftware.Gravia.Editor
{

    public class SelectObjects : EditorWindow
    {

        [MenuItem("Window/Select Objects")]
        static void Init()
        {
            // Get existing open window or if none, make a new one:
            SelectObjects window = (SelectObjects)EditorWindow.GetWindow(typeof(SelectObjects));
            window.Show();
        }

        void OnGUI()
        {
            if (GUILayout.Button("Select Rigidbodies"))
            {
                // Find all game objects with Rigidbodies on them.
                Selection.objects = GameObject.FindObjectsOfType<Rigidbody>().Select(rb => rb.gameObject).ToArray();
            }
        }
    }
}
2 Likes

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.

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?

No highlighting occurs, only sharing of the inspector window (as seen to the right of your screenshot).

That’s odd. What version of Unity are you using? I didn’t do anything special to get the highlighting to work.

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

I just tried in 2019.3.7, and it works fine for me:

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?

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:

public abstract class GenericConfigJointsList_Editor<T> : Editor
        where T : ConfigurableJoints
    {
        private T _configJoints;

        private void OnEnable()
        {
            if ( target == null ) return;
                                
            _configJoints = target as T;
        }

        public override void OnInspectorGUI()
        {
            DrawDefaultInspector();

            GUILayout.Space(10f);
           
            if (GUILayout.Button("Select All Joints", GUILayout.Height(_lineHeightSpace)))
            {
                Selection.objects = _configJoints.Joints.ToArray();
            }
           
            GUILayout.Space(10f);
                             
         }
    }

I managed to get it working with the help of @d

if (GUILayout.Button("Select All Joints", GUILayout.Height(_lineHeightSpace)))
{
    // Find all game objects with ConfigurableJoints on them.
    GameObject[] confJoints = GameObject.FindObjectsOfType<ConfigurableJoint>().Select(rb => rb.gameObject).ToArray();
               
    IEnumerable<GameObject> activeConfJoints = confJoints.Where(j => j.activeInHierarchy && j.name.Contains(_charJoints.SelectionSearchSubString));
                               
    Selection.objects = activeConfJoints.ToArray();
}

goyette for those interested:

2 Likes