如何仅在SetSearchFilter中过滤包含特定组件的对象? [英] How can I filter in SetSearchFilter only objects that contain specific component/s?

查看:140
本文介绍了如何仅在SetSearchFilter中过滤包含特定组件的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在CustomEditor脚本中,我为附着有特定组件的黄色对象着色(在本例中为Mesh Renderer).

In the CustomEditor script I color in yellow objects that have attached a specific component in this case Mesh Renderer.

using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
//Adapted from Unity3DCollege YouTube Video Tutorial https://www.youtube.com/watch?v=pdDrY8Mc2lU
[InitializeOnLoad]
public class CustomHierarchy : MonoBehaviour
{
    private static Vector2 offset = new Vector2(0, 2);
    public static Color gameObjectFontColor = Color.black;
    public static Color prefabOrgFontColor = Color.black;
    public static Color prefabModFontColor = Color.white;
    public static Color inActiveColor = new Color(0.01f, 0.4f, 0.25f);
    public static Color meshRendererColor = Color.yellow;
    public static List<string> componentsList = new List<string>();

    static CustomHierarchy()
    {
        EditorApplication.hierarchyWindowItemOnGUI += HandleHierarchyWindowItemOnGUI;
    }
    private static void HandleHierarchyWindowItemOnGUI(int instanceID, Rect selectionRect)
    {
        Color fontColor = gameObjectFontColor;
        Color backgroundColor = new Color(.76f, .76f, .76f);
        FontStyle styleFont = FontStyle.Normal;
        var obj = EditorUtility.InstanceIDToObject(instanceID);
        GameObject gameObj = EditorUtility.InstanceIDToObject(instanceID) as GameObject;

        if (Selection.instanceIDs.Contains(instanceID))
        {
            backgroundColor = new Color(0.24f, 0.48f, 0.90f);
        }
        if (obj != null)
        {
            var prefabType = PrefabUtility.GetPrefabType(obj);
            if (gameObj.activeInHierarchy == false)
            {
                backgroundColor = inActiveColor;
            }

            if (prefabType == PrefabType.PrefabInstance)
            {
                styleFont = FontStyle.Bold;
                PropertyModification[] prefabMods = PrefabUtility.GetPropertyModifications(obj);
                foreach (PropertyModification prefabMod in prefabMods)
                {
                    if (prefabMod.propertyPath.ToString() != "m_Name" && prefabMod.propertyPath.ToString() != "m_LocalPosition.x" && prefabMod.propertyPath.ToString() != "m_LocalPosition.y" && prefabMod.propertyPath.ToString() != "m_LocalPosition.z" && prefabMod.propertyPath.ToString() != "m_LocalRotation.x" && prefabMod.propertyPath.ToString() != "m_LocalRotation.y" && prefabMod.propertyPath.ToString() != "m_LocalRotation.z" && prefabMod.propertyPath.ToString() != "m_LocalRotation.w" && prefabMod.propertyPath.ToString() != "m_RootOrder" && prefabMod.propertyPath.ToString() != "m_IsActive")
                    {
                        if (gameObj.GetComponent<MeshRenderer>() == true)
                            fontColor = meshRendererColor;
                        else
                            fontColor = prefabModFontColor;

                        break;
                    }
                }
                if (fontColor != prefabModFontColor)
                {
                    if (gameObj.GetComponent<MeshRenderer>() == true)
                        fontColor = meshRendererColor;
                    else
                        fontColor = prefabOrgFontColor;
                }
            }
            else
            {
                if (gameObj.GetComponent<MeshRenderer>() == true)
                    fontColor = meshRendererColor;
            }
            Rect offsetRect = new Rect(selectionRect.position + offset, selectionRect.size);
            EditorGUI.DrawRect(selectionRect, backgroundColor);
            EditorGUI.LabelField(offsetRect, obj.name, new GUIStyle()
            {
                normal = new GUIStyleState() { textColor = fontColor },
                fontStyle = styleFont
            }
            );
        }
    }
}

在EditorWindow脚本中,我正在使用SetSearchFilter:

In the EditorWindow script I'm using the SetSearchFilter:

using System;
using UnityEditor;
using UnityEngine;
using System.Collections;
using System.Reflection;

public class HierarchyEditor : EditorWindow
{
    private static SearchableEditorWindow hierarchy { get; set; }
    private string filterText = "";

    [MenuItem("Tools/Hierarchy Editor")]
    public static void ShowWindow()
    {
        GetWindow<HierarchyEditor>("HierarchyEditor");
    }
    private void OnGUI()
    {
        CustomHierarchy.gameObjectFontColor = EditorGUILayout.ColorField("Original Font Color", CustomHierarchy.gameObjectFontColor);
        CustomHierarchy.prefabOrgFontColor = EditorGUILayout.ColorField("Prefab Original Font Color", CustomHierarchy.prefabOrgFontColor);
        CustomHierarchy.prefabModFontColor = EditorGUILayout.ColorField("Prefab Modified Font Color", CustomHierarchy.prefabModFontColor);
        CustomHierarchy.inActiveColor = EditorGUILayout.ColorField("Inactive Color", CustomHierarchy.inActiveColor);
        CustomHierarchy.meshRendererColor = EditorGUILayout.ColorField("Mesh Renderer Color", CustomHierarchy.meshRendererColor);

        filterText = GUI.TextField(new Rect(30,190,120,30),filterText, 25);

        SetSearchFilter(filterText, 1);
    }

    public const int FILTERMODE_ALL = 0;
    public const int FILTERMODE_NAME = 1;
    public const int FILTERMODE_TYPE = 2;

    public static void SetSearchFilter(string filter, int filterMode)
    {
        SearchableEditorWindow[] windows = (SearchableEditorWindow[])Resources.FindObjectsOfTypeAll(typeof(SearchableEditorWindow));

        foreach (SearchableEditorWindow window in windows)
        {
            if (window.GetType().ToString() == "UnityEditor.SceneHierarchyWindow")
            {
                hierarchy = window;
                break;
            }
        }

        if (hierarchy == null)
            return;

        MethodInfo setSearchType = typeof(SearchableEditorWindow).GetMethod("SetSearchFilter", BindingFlags.NonPublic | BindingFlags.Instance);
        object[] parameters = new object[] { filter, filterMode, false };

        setSearchType.Invoke(hierarchy, parameters); 
    }
}

在这里,我输入filterText TextField,在这种情况下,它是按名称过滤的.

Here I'm typing in the filterText TextField and it's filtering by name in this case.

但是我想按名称过滤,但也要仅过滤连接到它们的对象的Mesh Renderer组件.不是FILTERMODE_TYPE,而是已附加了Mesh Renderer组件的对象.因此,过滤器模式应为Name(1),而且还应同时使用网格渲染器过滤对象.

But I want to filter by name but also to filter only objects that attached to them a Mesh Renderer component. Not the FILTERMODE_TYPE but objects that have attached with Mesh Renderer component. So the filter mode should be Name(1) but also to filter at the same time objects with mesh renderer.

我试图在OnGUI中添加两行: 这两行是:

I tried to add to the OnGUI two lines: The two lines are:

System.Type type = SceneModeUtility.SearchBar(typeof(BoxCollider), typeof(MeshRenderer));
SceneModeUtility.SearchForType(type);

但是随后在EditorWindow中,我看到了3个图标All BoxCollider MeshRenderer. 如果单击BoxCollider,它将使用boxcollider过滤所有对象,但是当我在层次结构搜索栏中键入名称时,它将过滤具有名称和box collider的所有对象,但是当我再次单击editorwindow时,它将其更改为所有图标.网格渲染器也是如此.

But then in the EditorWindow I see 3 icons All BoxCollider MeshRenderer. If I click on BoxCollider it's filtering all objects with boxcollider but then when I'm typing a name in the hierarchy search bar it will filter all objects with the name and box collider but then when I click on the editorwindow again it's changing it to the All icon. Same for the meshrenderer.

我不能同时选择boxcollider和meshrenderer,我只能选择其中之一.

And I can't select both boxcollider and meshrenderer I can select only one of them.

EditorWindow的屏幕截图:

Screenshot of the EditorWindow:

private void OnGUI()
    {
        CustomHierarchy.gameObjectFontColor = EditorGUILayout.ColorField("Original Font Color", CustomHierarchy.gameObjectFontColor);
        CustomHierarchy.prefabOrgFontColor = EditorGUILayout.ColorField("Prefab Original Font Color", CustomHierarchy.prefabOrgFontColor);
        CustomHierarchy.prefabModFontColor = EditorGUILayout.ColorField("Prefab Modified Font Color", CustomHierarchy.prefabModFontColor);
        CustomHierarchy.inActiveColor = EditorGUILayout.ColorField("Inactive Color", CustomHierarchy.inActiveColor);
        CustomHierarchy.meshRendererColor = EditorGUILayout.ColorField("Mesh Renderer Color", CustomHierarchy.meshRendererColor);

        multipleComponents = GUI.Toggle(new Rect(30, 160, 120, 30), multipleComponents, "Multiple components");
        if(multipleComponents == true)
        {
            GUI.enabled = true;
        }
        else
        {
            GUI.enabled = false;
        }
        multipleComponentsString = GUI.TextField(new Rect(30, 180, 120, 30), multipleComponentsString, 25);

        GUI.enabled = true;
        filterText = GUI.TextField(new Rect(30, 230, 120, 30), filterText, 25);

        System.Type type = SceneModeUtility.SearchBar(typeof(BoxCollider), typeof(MeshRenderer));
        SceneModeUtility.SearchForType(type);
    }

推荐答案

我注意到您正在使用反射来做到这一点.不用了有一个未公开的API,称为SceneModeUtility,可用于在编辑器中搜索对象.请参见此处的非官方API.使用Chrome浏览器可以轻松将其翻译成英文.

I noticed you're using reflection to do this. You don't have to. There is an undocumented API called SceneModeUtility that can be used to search Objects in the Editor. See the non-official API for this here. It can be easily translated into English with a Chrome browser.

如果只想在编辑器的SearchField中搜索和筛选带有组件(MeshRenderer)的对象,则:

If you just want to search and filter an Object with a component (MeshRenderer) in the SearchField in the Editor:

SceneModeUtility.SearchForType(typeof(MeshRenderer));

要使用GameObject上的多个组件过滤搜索并返回结果:

To filter the search with multiple components on a GameObject and return the result:

System.Type type = SceneModeUtility.SearchBar(typeof(MeshRenderer), typeof(Rigidbody));

您可以根据需要将任意数量的组件传递给SearchBar函数.

You can pass as many components as you wish to the SearchBar function.

这篇关于如何仅在SetSearchFilter中过滤包含特定组件的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆