Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

293
Views
Collapsing selected Game Objects in the hierarchy

I am collapsing a selected parent gameObject with this editor script. It all works well but it also collapses other expanded gameObjects which should not happen. For example under two different parents, if I collapse one parent gameObject, even the other parent gameObject gets collapsed. How do I not let this happen?

I feel the problem is at rootGameObjects.AddRange (SceneManager.GetSceneAt (i).GetRootGameObjects ()); where it takes the root gameObject in a scene but not the selected gameObject in the hierarchy.

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

public static class CollapseTools {
    private static int wait = 0;
    private static int undoIndex;

    public static void CollapseGameObjects () {
        EditorApplication.update -= CollapseGameObjects;
        CollapseGameObjects (new MenuCommand (null));
    }

    [MenuItem ("GameObject/Collapse GameObjects", priority = 40)]
    private static void CollapseGameObjects (MenuCommand command) {
        // This happens when this button is clicked via hierarchy's right click context menu
        // and is called once for each object in the selection. We don't want that, we want
        // the function to be called only once
        if (command.context) {
            EditorApplication.update -= CollapseGameObjects;
            EditorApplication.update += CollapseGameObjects;

            return;
        }

        List<GameObject> rootGameObjects = new List<GameObject> ();
#if UNITY_2018_3_OR_NEWER
        // Check if a prefab stage is currently open
        var prefabStage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage ();
        if (prefabStage != null && prefabStage.stageHandle.IsValid ())
            rootGameObjects.Add (prefabStage.prefabContentsRoot);
        else
#endif
        {
            int sceneCount = SceneManager.sceneCount;
            for (int i = 0; i < sceneCount; i++)
                rootGameObjects.AddRange (SceneManager.GetSceneAt (i).GetRootGameObjects ());
        }

        if (rootGameObjects.Count > 0) {
            Undo.IncrementCurrentGroup ();
            Selection.objects = Selection.objects;
            undoIndex = Undo.GetCurrentGroup ();

            Selection.objects = rootGameObjects.ToArray ();

            EditorApplication.update -= CollapseHelper;
            EditorApplication.update += CollapseHelper;
        }
    }

    private static void CollapseHelper () {
        if (wait < 1) // Increase the number if script doesn't always work
            wait++;
        else {
            EditorApplication.update -= CollapseHelper;
            wait = 0;

            EditorWindow focusedWindow = EditorWindow.focusedWindow;
            if (focusedWindow != null)
                focusedWindow.SendEvent (new Event { keyCode = KeyCode.LeftArrow, type = EventType.KeyDown, alt = true });

            Undo.RevertAllDownToGroup (undoIndex);
        }
    }
}
over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

enter image description here

When it comes to Unity, nothing beats reflection:

using UnityEditor;
using UnityEngine;

internal class MyClass : EditorWindow
{
    private void OnGUI()
    {
        using (var scope = new EditorGUI.DisabledGroupScope(Selection.activeGameObject == null))
        {
            if (GUILayout.Button("Expand Recursive"))
            {
                var type = typeof(EditorWindow).Assembly.GetType("UnityEditor.SceneHierarchyWindow");
                var window = GetWindow(type);
                var exprec = type.GetMethod("SetExpandedRecursive");
                exprec!.Invoke(window, new object[] {Selection.activeGameObject.GetInstanceID(), true});
            }
        }
    }

    [MenuItem("TEST/TEST")]
    private static void Init()
    {
        GetWindow<MyClass>();
    }
}

Check SceneHierarchyWindow class for other things you could hook into.

Now you have another problem, when you have multiple hierarchy windows open, I'll let you solve that one :)

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!