Unity3D Editor 编辑器扩展实战 Project窗口全文件夹折叠

环境:Unity2017.2 语言:C#

总起:

在使用Project窗口时,总在不停地找资源和找代码过程中,将Project中的文件夹展开,导致窗口的混乱,虽然在按住Alt的情况下点击三角能够全部折叠一组的文件夹,但是这样做也比较麻烦。

所以有没有办法按下一个快捷键将所有文件夹全部折叠呢?

今天就为大家带来本人最新研究的一种对Editor的扩展(仅在2017版本中试验过,因为用到了反射技术所以不保证其他版本通用)。

折叠脚本:

新建Editor文件夹,再在其中新建一个脚本:

using System.Collections;
using System.Linq;
using System.Reflection;
using UnityEditor;

// CollapseFolders.cs
public static class CollapseFolders
{
    [MenuItem("Assets/折叠所有文件夹 &c", false, 30)]
    public static void SetProjectBrowserFoldersCollapsed()
    {
        var assembly = Assembly.GetAssembly(typeof(Editor));
        var type = assembly.GetType("UnityEditor.ProjectBrowser");

        if (type == null)
            return;

        var browserField = type.GetField("s_LastInteractedProjectBrowser", BindingFlags.Public | BindingFlags.Static);
        var browser = browserField.GetValue(null);

        if (browser == null)
            return;

        // 确定窗口模式是否是单列
        var modeField = type.GetField("m_ViewMode", BindingFlags.NonPublic | BindingFlags.Instance);
        bool isOne = (int) modeField.GetValue(browser) == 0;

        // 获取文件夹树
        var treeField = type.GetField(isOne ? "m_AssetTree" : "m_FolderTree", BindingFlags.NonPublic | BindingFlags.Instance);
        var tree = treeField.GetValue(browser);

        var dataProperty = treeField.FieldType.GetProperty("data", BindingFlags.Instance | BindingFlags.Public);
        var data = dataProperty.GetValue(tree, null);

        var getRowsMethod = dataProperty.PropertyType.GetMethod("GetRows", BindingFlags.Instance | BindingFlags.Public);
        var setExpandedMethods = dataProperty.PropertyType.GetMethods(BindingFlags.Instance | BindingFlags.Public).ToList().FindAll(method => method.Name == "SetExpanded");
        var setExpandedMethod = setExpandedMethods[0];

        var rows = (IEnumerable) getRowsMethod.Invoke(data, null);
        bool first = true;
        // 遍历当前的行将其折叠
        foreach (var obj in rows)
        {
            if (first && !isOne)
            {
                var itemType = obj.GetType();
                var nameField = itemType.GetField("m_DisplayName", BindingFlags.Instance | BindingFlags.NonPublic);
                if (nameField != null)
                {
                    string name = (string) nameField.GetValue(obj);
                    if (name == "Assets")
                    {
                        first = false;
                        setExpandedMethod.Invoke(data, new object[]{obj, true});
                        continue;
                    }
                }
            }
            setExpandedMethod.Invoke(data, new object[] {obj, false});
        }
        AssetDatabase.Refresh();
    }
}

思路就是通过反射出当前的Project窗口对应的类,取到其中每个条目对应的元素,然后将其折叠,最后刷新一下AssetDatabase就OK。


猜你喜欢

转载自blog.csdn.net/u012632851/article/details/80841606