using System.Collections.Generic; | |
using System.IO; | |
using UnityEditor; | |
using UnityEngine; | |
using UnityEngine.SceneManagement; | |
public static class EditorCollapseAll | |
{ | |
private static int wait = 0; | |
private static int undoIndex; | |
[MenuItem( "Assets/Collapse All", priority = 1000 )] | |
public static void CollapseFolders() | |
{ | |
FileSystemInfo[] rootItems = new DirectoryInfo( Application.dataPath ).GetFileSystemInfos(); | |
List<Object> rootItemsList = new List<Object>( rootItems.Length ); | |
for( int i = 0; i < rootItems.Length; i++ ) | |
{ | |
Object asset = AssetDatabase.LoadAssetAtPath<Object>( "Assets/" + rootItems[i].Name ); | |
if( asset != null ) | |
rootItemsList.Add( asset ); | |
} | |
if( rootItemsList.Count > 0 ) | |
{ | |
Undo.IncrementCurrentGroup(); | |
Selection.objects = Selection.objects; | |
undoIndex = Undo.GetCurrentGroup(); | |
EditorUtility.FocusProjectWindow(); | |
Selection.objects = rootItemsList.ToArray(); | |
EditorApplication.update -= CollapseHelper; | |
EditorApplication.update += CollapseHelper; | |
} | |
} | |
public static void CollapseGameObjects() | |
{ | |
EditorApplication.update -= CollapseGameObjects; | |
CollapseGameObjects( new MenuCommand( null ) ); | |
} | |
[MenuItem( "GameObject/Collapse All", 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; | |
} | |
} | |
[MenuItem( "CONTEXT/Component/Collapse All", priority = 1400 )] | |
private static void CollapseComponents( MenuCommand command ) | |
{ | |
// Credit: https://forum.unity.com/threads/is-it-possible-to-fold-a-component-from-script-inspector-view.296333/#post-2353538 | |
ActiveEditorTracker tracker = ActiveEditorTracker.sharedTracker; | |
for( int i = 0, length = tracker.activeEditors.Length; i < length; i++ ) | |
tracker.SetVisible( i, 0 ); | |
EditorWindow.focusedWindow.Repaint(); | |
} | |
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 ); | |
} | |
} | |
} |
This comment has been minimized.
This comment has been minimized.
Hey this is cool! Thankyou! |
This comment has been minimized.
This comment has been minimized.
FYI the same functionality is achieved by simply holding Alt when clicking a foldout |
This comment has been minimized.
This comment has been minimized.
That's right Alt + LMB on the disclosing arrow achieves the exact same thing. Came here 'cause I'm looking for collapse all components in inspector. |
This comment has been minimized.
This comment has been minimized.
Added! Simply right click a component and select "Collapse All". |
This comment has been minimized.
This comment has been minimized.
Tried using the updated code just now and Inspector Collapse All does not work, at least not on Unity 2018.4.0f1 Edit: It has started working after a little while ( after restarting Unity I think). But there is still a problem: When navigating away and back from a collapsed game object the inspector shows the object expanded, in other words it does not seem to remember the collapsed state of the object. Is there any way to fix this issue? |
This comment has been minimized.
This comment has been minimized.
You can add this code to the top of CollapseComponents function: if( Selection.activeGameObject )
{
foreach( Component component in Selection.activeGameObject.GetComponents<Component>() )
UnityEditorInternal.InternalEditorUtility.SetIsInspectorExpanded( component, false );
} But be aware that this will affect that component type (e.g. Transform) on ALL objects. There is no way to set the collapsed state of a component permanantly object-wise. |
This comment has been minimized.
This comment has been minimized.
Not ideal but I might give it a try. Thanks very much. |
This comment has been minimized.
How To
Just put it in Assets/Editor folder of your project.
Collapsing Hierarchy View
To collapse all GameObjects in the currently active Hierarchy window, either use the GameObject menu or right click a GameObject and select "Collapse All".
Collapsing Project View
To collapse all folders in Project window, either use the Assets menu or right click an asset and select "Collapse All". Note that folders containing the selected assets will not be collapsed.
Collapsing Components
To collapse all components in the Inspector window, right click a component and select "Collapse All".