Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Focus folder in Project Window

Discussion in 'Immediate Mode GUI (IMGUI)' started by Wattosan, Sep 23, 2018.

  1. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    456
    Hey,

    Using editor code I would like to focus a certain folder in the Project window.
    I know how to create editor buttons, menu items etc but I have not found a way to focus a folder in project window. I have focused assets, which take me to a certain folder. But if a folder is empty is there a way to focus it?

    There should be a way because the Favorites system seems to use that.

    Any ideas?
    Thanks!
     
  2. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    456
  3. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    hi @F-R-O-S-T-Y

    I'm not sure how you would completely do it...

    This is from the forums modified by me, I have no idea of the origin. Just have it in my notes.

    Feels bit hacky, but at least it selects the folder - empty or not.

    However, it doesn't navigate into that folder, like you would double click it in Project view.

    This is just a demo (works from MB), GameObjects has item that you can click to navigate to folder Assets/Test.

    Code (CSharp):
    1.      [MenuItem("GameObject/TEST - SelectPath")]
    2.     static void SelectPath()
    3.     {
    4.         Debug.Log("SelectPath");
    5.  
    6.         string path =  "Assets/Test";
    7.  
    8.         UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath(path, typeof(UnityEngine.Object));
    9.  
    10.         Selection.activeObject = obj;
    11.  
    12.         EditorGUIUtility.PingObject(obj);
    13.     }
     
    Sebastian_Trick3d and Wattosan like this.
  4. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    456
    Thank you!

    I modified it a little bit. It is also important to call
    EditorUtility.FocusProjectWindow();
    before
    Selection.activeObject
    . I did not need to call
    EditorGUIUtility.PingObject(obj);


    Final code:
    Code (CSharp):
    1. EditorUtility.FocusProjectWindow();
    2.  
    3. Object obj = AssetDatabase.LoadAssetAtPath<Object>("Assets/Art/Models");
    4.  
    5. Selection.activeObject = obj;

    Thanks again! :)
     
  5. Wattosan

    Wattosan

    Joined:
    Mar 22, 2013
    Posts:
    456
    Okay, never mind. While it does focus, for some reason when I add a new folder path to focus (using editor buttons), I have to click the editor button twice. With first click it takes me to one of the previous folders I focused (but I think the selection is correct), and with the second click the correct folder is focused in the project view (project view navigates to the correct path).

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. public class MenuItems {
    5.     [MenuItem("Favourites/Trees")]
    6.     private static void SelectFolder()
    7.     {
    8.         EditorUtility.FocusProjectWindow();
    9.  
    10.         Object obj = AssetDatabase.LoadAssetAtPath<Object>("Assets/Scripts/Player/Okay");
    11.  
    12.         Selection.activeObject = obj;
    13.     }
    14. }
     
    LabOSM likes this.
  6. StephenWebb

    StephenWebb

    Joined:
    Feb 3, 2013
    Posts:
    11
    In my use case, I have an EditorWindow system and a collection of objects in a scriptable object asset I call a Datastore.
    One of the properties of items in the datastore might be called 'Model',


    GUILayout.BeginHorizontal();
    {
    selectedItem.Model = (GameObject)EditorGUILayout.ObjectField("Model", selectedItem.Model, typeof(GameObject, true));
    if (GUILayout.Button("Locate Item"))
    {
    EditorUtility.FocusProjectWindow();
    Selection.activeObject = selectedItem.Model;
    }
    }
    GUILayout.EndHorizontal();
    This works perfectly fine if you need to use it. The key is, as you've said
    'EditorUtility.FocusProjectWindow();
    Selection.activeObject = selectedItem.Model;'

    here's a pic:
     

    Attached Files:

    • pic.PNG
      pic.PNG
      File size:
      622.5 KB
      Views:
      379
  7. Cirtoyt

    Cirtoyt

    Joined:
    Dec 11, 2019
    Posts:
    4
    I know this is a really old thread, but I've been working on a templated script generation system within my custom editor and this thread came up first on google a lot, and I found a solution to this issue from another person's (roroco's) solution posted on another thread that needed a little change to work for direct copy/pasting: http://answers.unity.com/answers/1415446/view.html

    Their method uses the following code that finds the last interacted Project Browser and calls the ShowFolderContents function on the Project Browser instance, which selects and shows that folder in that Project Browser window. This ensures that if you have a two column layout or even multiple Project Browser windows open at once, the latest interacted window will correctly select the folder you wish. To ensure this works, make sure to also call EditorUtility.FocusProjectWindow() to handle issues with the Project Browser being hidden behind other windows that share the same docked area, such as when you are on the Console Log when calling this system. In my instance, I can then call my desired function after this "ProjectWindowUtil.CreateScriptAssetFromTemplateFile(templatePath, template.defaultFileName);" and that all works out for me no matter which window is currently in focus. Just make sure the path you send in doesn't have a slash at the end and you should be good :D

    Here is the functioning code:

    string path = "Assets/DesiredFolderPath"
    UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath(path, typeof(UnityEngine.Object));

    EditorUtility.FocusProjectWindow();

    var pt = Type.GetType("UnityEditor.ProjectBrowser,UnityEditor");
    var ins = pt.GetField("s_LastInteractedProjectBrowser", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public).GetValue(null);
    var showDirMeth = pt.GetMethod("ShowFolderContents", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    showDirMeth.Invoke(ins, new object[] { obj.GetInstanceID(), true });
     
    Last edited: Dec 11, 2022
    woody-starberry and comealong like this.
  8. ichenpipi

    ichenpipi

    Joined:
    Feb 24, 2021
    Posts:
    3
    This works! Thank you!
     
  9. lgarczyn

    lgarczyn

    Joined:
    Nov 23, 2014
    Posts:
    66
    Much simpler solution:

    AssetDatabase.OpenAsset(folderAssetObject);