介绍

Unity 中的 Project 双列视图提供了很好的过滤项显示支持:可以将符合条件的项目显示在双列视图中的右侧视图中。

此功能非常好用,经常在搜索、选择资源依赖项等处使用。

问题

资源右键菜单中 Select Dependencies 功能会将当前资源依赖的所有资源都选中,并且会显示在 Project 双列视图中的右侧视图中。

如果依赖的资源有多种类型,那么 Inspector 视图中会分别显示出类型及其数量。

但是问题在于点击 Inspector 视图中的任一类型资源,Project 双列视图中的的右侧视图并不会显示此类型的所有资源;界面直接退回到了默认的目录显示类型,即只会显示最后一个目录内的依赖资源。而实际上需要显示为类似 Select Dependencies 之后的效果。

解决方案

官方修正

最简单的方式就是 Unity 官方修改 Inspector 代码,将更新过滤项显示方法调用加入到正确位置(下面方法 31 行下面)即可。UnityCsReference/InspectorWindow.cs at master · Unity-Technologies/UnityCsReference

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void DrawSelectionPickerList()
{
    if (m_TypeSelectionList == null)
        m_TypeSelectionList = new TypeSelectionList(Selection.objects);

    // Force header to be flush with the top of the window
    GUILayout.Space(0);

    Editor.DrawHeaderGUI(null, Selection.objects.Length + " Objects");

    GUILayout.Label("Narrow the Selection:", EditorStyles.label);
    GUILayout.Space(4);

    Vector2 oldSize = EditorGUIUtility.GetIconSize();
    EditorGUIUtility.SetIconSize(new Vector2(16, 16));
    foreach (TypeSelection ts in m_TypeSelectionList.typeSelections)
    {
        Rect r = GUILayoutUtility.GetRect(16, 16, GUILayout.ExpandWidth(true));
        if (GUI.Button(r, ts.label, styles.typeSelection))
        {
            Selection.objects = ts.objects;
            Event.current.Use();
        }
        if (GUIUtility.hotControl == 0)
            EditorGUIUtility.AddCursorRect(r, MouseCursor.Link);
        GUILayout.Space(4);
    }
    EditorGUIUtility.SetIconSize(oldSize);
}

自定义显示

其实 Unity 官方有提供现成的方法,但由于方法是私有的,不能直接调用。好在 C# 可以通过反射调用私有方法。

将以下代码放在 Editor 目录内,然后使用快捷键 Ctrl+Shift+G 即可将所有选中项列在 Project 双列视图中的右侧视图中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;

public static class ShowSelectedObjectsInProject
{
    [MenuItem("Tools/Selection/Show Selected Objects in Project %#g")]
    public static void ShowSelectedObjectsInLastInteractedProjectBrowser()
    {
        if (Selection.objects == null || Selection.objects.Length <= 1)
        {
            return;
        }

        Type projectBrowserType = Type.GetType("UnityEditor.ProjectBrowser,UnityEditor");
        if (projectBrowserType == null)
        {
            Debug.LogError("Can't find UnityEditor.ProjectBrowser type!");
            return;
        }

        FieldInfo lastProjectBrowser = projectBrowserType.GetField("s_LastInteractedProjectBrowser",
            BindingFlags.Static | BindingFlags.Public);
        if (lastProjectBrowser == null)
        {
            Debug.LogError("Can't find s_LastInteractedProjectBrowser field!");
            return;
        }

        object lastProjectBrowserInstance = lastProjectBrowser.GetValue(null);
        FieldInfo projectBrowserViewMode =
            projectBrowserType.GetField("m_ViewMode", BindingFlags.Instance | BindingFlags.NonPublic);
        if (projectBrowserViewMode == null)
        {
            Debug.LogError("Can't find m_ViewMode field!");
            return;
        }

        // 0 - one column, 1 - two column
        int viewMode = (int)projectBrowserViewMode.GetValue(lastProjectBrowserInstance);
        if (viewMode != 1)
        {
            return;
        }

        MethodInfo showSelectedObjects = projectBrowserType.GetMethod(
            "ShowSelectedObjectsInLastInteractedProjectBrowser", BindingFlags.NonPublic | BindingFlags.Static);
        if (showSelectedObjects != null)
        {
            showSelectedObjects.Invoke(null, null);
        }
        else
        {
            Debug.LogError("Can't find ShowSelectedObjectsInLastInteractedProjectBrowser method!");
        }
    }
}

下载

networm/ShowSelectedObjectsInProject: Show selected objects when enable two column mode in Project view.

参考资料

How to nicely select item in the Unity’s two-column Project Browser | CODE STAGE