Search Unity

Is it possible to fold a component from script? (inspector view)

Discussion in 'Scripting' started by Issam, Feb 6, 2015.

  1. Issam

    Issam

    Joined:
    Dec 18, 2012
    Posts:
    37
    I have a custom importer that add colliders to imported objects, I would like those colliders component to be folded by default in the inspector view so they don't show their outlines in the scene view. Is there a way to tell the default inspector view that a component is folded by default?
     
  2. Member123456

    Member123456

    Joined:
    Oct 17, 2012
    Posts:
    237
    I am also looking for an answer to this.
     
  3. TMPxyz

    TMPxyz

    Joined:
    Jul 20, 2012
    Posts:
    766
    There's a way, but you need to use reflection and access the internal APIs

    Code (CSharp):
    1. var insWnd = EditorWindow.focusedWindow;
    2. ActiveEditorTracker tracker = //use Reflection to call InspectorWindow.GetTracker();
    3. var editors = tracker.activeEditors;
    4. for (int eidx = 0; eidx < editors.Length; ++eidx )
    5. {
    6.     tracker.SetVisible(eidx, 0); //to fold
    7.     //var e = editors[eidx];                              
    8.     //RCall.CallMtd("UnityEditor.Editor", "InternalSetHidden", e, true); //to hide
    9. }
     
  4. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    @TMPxyz thanks for your hint!

    Here is a working example based on the TMPxyz's post for those who will look for it:

    Code (CSharp):
    1. // in my case first of all I need to select object
    2. Selection.activeTransform = go.transform;
    3.  
    4. // then I need to skip 1 frame to let Inspector initialize on new object
    5. // all this code is running in the IEnumerator which is started as coroutine
    6. yield return new WaitForEndOfFrame();
    7.  
    8. // now I need to focus on the Inspector view
    9. // to make sure EditorWindow.focusedWindow will return instance of the InspectorWindow
    10. EditorApplication.ExecuteMenuItem("Window/Inspector");
    11.  
    12. EditorWindow inspectorWindow = EditorWindow.focusedWindow;
    13. ActiveEditorTracker tracker = (ActiveEditorTracker)inspectorWindow.GetType().GetMethod("GetTracker").Invoke(inspectorWindow, null);
    14.  
    15. Editor[] editors = tracker.activeEditors;
    16.  
    17. for (int i = 0; i < editors.Length; i++)
    18. {
    19.     // in my case I need to keep one component unfolded (expanded, visible)
    20.     // I use Instance ID or local file ID to identify component instance
    21.     // editors[i].target links to the component, so I can get the id of the component
    22.     // and compare it with the previously saved id of the component I need
    23.     // to keep unfolded
    24.     long id = CSObjectTools.GetLocalIdentifierInFileForObject(editors[i].target);
    25.     tracker.SetVisible(i, id != componentId ? 0 : 1);
    26. }
    BTW, you also may use UnityEditorInternal.InternalEditorUtility.SetIsInspectorExpanded() method to expand and collapse components.

    Main difference between tracker visibility and SetIsInspectorExpanded - first one will change expanded state temporary, it doesn't saves if you change selection and select target object again, where second will change expanded state permanently and it will survive after you re-select object.
     
    TMPxyz likes this.
  5. mrtkhosravi

    mrtkhosravi

    Joined:
    Nov 9, 2014
    Posts:
    198
    Can you provide an example that shows how it can be done with this method? I couldn't find anything on the web. I need to force expand inspector for some component but as you suggested the tracker.SetVisible method is temporary and when I select something else in hierarchy and select back the object, the component becomes collapsed again.
     
  6. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Hey, @mrtkhosravi !

    Just call InternalEditorUtility.SetIsInspectorExpanded for your component instance like this:

    Code (CSharp):
    1. MyComponentType myComponent = selectedGameObject.GetComponent<MyComponentType>();
    2. UnityEditorInternal.InternalEditorUtility.SetIsInspectorExpanded(myComponent, true);
    3.  
    4. // here is a signature of the SetIsInspectorExpanded:
    5. // public static extern void SetIsInspectorExpanded(UnityEngine.Object obj, bool isExpanded);
     
  7. mrtkhosravi

    mrtkhosravi

    Joined:
    Nov 9, 2014
    Posts:
    198
    I tested it for terrain and unfortunately it doesn't work.
     
  8. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,931
    Have you tried to re-select object with your Terrain component?
    Looks like inspector should be refreshed somehow to immediately display changes.
    It works for me if I manually re-select object after running the code. I guess there should be some way to refresh inspector from code to avoid re-selecting.
     
  9. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    393
    Code (CSharp):
    1. UnityEditorInternal.InternalEditorUtility.SetIsInspectorExpanded(myComponent, true);
    2.             var go = Selection.activeGameObject;
    3.             Selection.activeGameObject = null;
    4.             Selection.activeGameObject = go;

    thanks
     
  10. andersemil

    andersemil

    Joined:
    Feb 2, 2015
    Posts:
    112
    Doesn't work on my 2018.4.9f1. Only if I change selection and then back to the same gameobject is the component expanded.
     
    shieldgenerator7 likes this.
  11. shieldgenerator7

    shieldgenerator7

    Joined:
    Dec 20, 2015
    Posts:
    39
    The top line worked for me in Unity 2020.3.23f1 without any other code. Thanks!