Setting Selection with multiple objects

Hi,

I am trying to select several objects in the hierarchy view from my EditorWindow script. I have tried to change the selection by assigning an array to Selection.objects, but that doesn’t seem to work, the selection simply stays as is (no error though).

Is there anything I have to do in addition to setting the Selection, like calling some Update() method or anything?

Thanks for your help!

Have you tried Selection.gameObjects ?

That seems to be read-only (as is Selection.transforms).

Ah, yes… But .objects should work. Can you post snippet of your code?

I’d like to select all child objects of a certain type whenever certain nodes are selected. I’m doing

using UnityEngine;
using System.Collections;
using UnityEditor;

public class MyEditorWindow : EditorWindow
{
        [...]
        
        void OnSelectionChange ()
        {
                GameObject[] selectedObjs = Selection.gameObjects;

                if (Selection.GetFiltered (typeof(MyNode), SelectionMode.TopLevel).Length == selectedObjs.Length) {
                        foreach (GameObject node in selectedObjs) {
                                node.GetComponent<MyNode> ().SetSelected ();
                        }
                }
        }
}

which in turn calls

using UnityEngine;
using System.Collections.Generic;
using UnityEditor;

public class MyNode : MonoBehaviour
{
   
        [..]

        public void SetSelected ()
        {
                GameObject[] currentSelection = Selection.gameObjects;
                ArrayUtility.Remove (ref currentSelection, gameObject);

                foreach (MySubNode subNode in GetComponentsInChildren<MySubNode>()) {
                        ArrayUtility.Add (ref currentSelection, subNode.gameObject);
                }

                Selection.objects = currentSelection;

        }
}

Unity appear to not allow a selection to change from the OnSelectionChange callback, which makes sense since it could easily create a stack overflow.

Here’s a way around it;

using UnityEngine;
using System.Collections.Generic;
using UnityEditor;

public class MyNode : MonoBehaviour
{
    public static UnityEngine.Object[] selection;

    public void SetSelected ()
    {
        GameObject[] currentSelection = Selection.gameObjects;
        ArrayUtility.Remove (ref currentSelection, gameObject);
        foreach (MySubNode subNode in GetComponentsInChildren<MySubNode>())
        {
            ArrayUtility.Add (ref currentSelection, subNode.gameObject);
        }

        selection = currentSelection;
    }
}
using UnityEngine;
using System.Collections;
using UnityEditor;
public class MyEditorWindow : EditorWindow
{
    [MenuItem("Window/Test")]
    public static void Menu()
    {
        EditorWindow.GetWindow<MyEditorWindow>();
    }

    void OnSelectionChange ()
    {
        GameObject[] selectedObjs = Selection.gameObjects;
        if (Selection.GetFiltered (typeof(MyNode), SelectionMode.TopLevel).Length == selectedObjs.Length)
        {
            foreach (GameObject node in selectedObjs)
            {
                node.GetComponent<MyNode> ().SetSelected ();
            }
        }
    }

    void Update()
    {
        if (MyNode.selection != null && MyNode.selection.Length != 0)
        {
            Selection.objects = MyNode.selection;
            MyNode.selection = null;
        }
    }
}
1 Like

Yes, you’re right not allowing selection changes from OnSelectionChange() makes sense… Your modification worked like a charm, thanks a lot!