Version: 2023.1

SearchUtils

class in UnityEditor.Search

切换到手册

描述

Provides various utility functions that are used by SearchProvider.

using System;
using System.Collections;
using System.Globalization;
using System.Linq;
using UnityEditor.Search;
using UnityEditor;
using UnityEngine;

/// <summary>
/// Custom provider showing how to implement a custom Query Engine supporting a Spatial search filter.
/// </summary>
public static class SpatialProvider
{
    internal static string type = "spl";
    internal static string displayName = "Spatial";

    static GameObject[] s_GameObjects;
    static QueryEngine<GameObject> s_QueryEngine;

    [SearchItemProvider]
    internal static SearchProvider CreateProvider()
    {
        return new SearchProvider(type, displayName)
        {
            active = false,
            filterId = "spl:",
            onEnable = OnEnable,
            fetchItems = (context, items, provider) => SearchItems(context, provider),
            fetchLabel = FetchLabel,
            fetchDescription = FetchDescription,
            fetchThumbnail = FetchThumbnail,
            fetchPreview = FetchPreview,
            trackSelection = TrackSelection,
            isExplicitProvider = false,
        };
    }

    static void OnEnable()
    {
        s_GameObjects = SearchUtils.FetchGameObjects().ToArray();
        s_QueryEngine = new QueryEngine<GameObject>();

        // Id supports all operators
        s_QueryEngine.AddFilter("id", go => go.GetInstanceID());
        // Name supports only :, = and !=
        s_QueryEngine.AddFilter("n", go => go.name, new[] {":", "=", "!="});

        // Add distance filtering. Does not support :.
        s_QueryEngine.AddFilter("dist", DistanceHandler, DistanceParamHandler, new[] {"=", "!=", "<", ">", "<=", ">="});
    }


    static IEnumerator SearchItems(SearchContext context, SearchProvider provider)
    {
        var query = s_QueryEngine.ParseQuery(context.searchQuery);
        if (!query.valid)
            yield break;

        var filteredObjects = query.Apply(s_GameObjects);
        foreach (var filteredObject in filteredObjects)
        {
            yield return provider.CreateItem(filteredObject.GetInstanceID().ToString(), null, null, null, filteredObject.GetInstanceID());
        }
    }


    static string FetchLabel(SearchItem item, SearchContext context)
    {
        if (item.label != null)
            return item.label;

        var go = ObjectFromItem(item);
        if (!go)
            return item.id;

        var transformPath = SearchUtils.GetTransformPath(go.transform);
        var components = go.GetComponents<Component>();
        if (components.Length > 2 && components[1] && components[components.Length - 1])
            item.label = $"{transformPath} ({components[1].GetType().Name}..{components[components.Length - 1].GetType().Name})";
        else if (components.Length > 1 && components[1])
            item.label = $"{transformPath} ({components[1].GetType().Name})";
        else
            item.label = $"{transformPath} ({item.id})";

        return item.label;
    }


    static string FetchDescription(SearchItem item, SearchContext context)
    {
        var go = ObjectFromItem(item);
        return (item.description = SearchUtils.GetHierarchyPath(go));
    }


    static Texture2D FetchThumbnail(SearchItem item, SearchContext context)
    {
        var obj = ObjectFromItem(item);
        if (obj == null)
            return null;

        return item.thumbnail = GetThumbnailForGameObject(obj);
    }

    static Texture2D FetchPreview(SearchItem item, SearchContext context, Vector2 size, FetchPreviewOptions options)
    {
        var obj = ObjectFromItem(item);
        if (obj == null)
            return item.thumbnail;

        var assetPath = SearchUtils.GetHierarchyAssetPath(obj, true);
        if (string.IsNullOrEmpty(assetPath))
            return item.thumbnail;

        if (options.HasFlag(FetchPreviewOptions.Large))
        {
            if (AssetPreview.GetAssetPreview(obj) is Texture2D tex)
                return tex;
        }
        return GetAssetPreviewFromPath(assetPath, size, options);
    }


    static void TrackSelection(SearchItem item, SearchContext context)
    {
        var obj = ObjectFromItem(item);
        if (obj)
            Selection.activeGameObject = obj;
        if (SceneView.lastActiveSceneView != null)
            SceneView.lastActiveSceneView.FrameSelected();
    }

    static float DistanceHandler(GameObject go, Vector3 p)
    {
        return (go.transform.position - p).magnitude;
    }

    static Vector3 DistanceParamHandler(string param)
    {
        if (param == "selection")
        {
            var centerPoint = Selection.gameObjects.Select(go => go.transform.position).Aggregate((v1, v2) => v1 + v2);
            centerPoint /= Selection.gameObjects.Length;
            return centerPoint;
        }

        if (param.StartsWith("[") && param.EndsWith("]"))
        {
            param = param.Trim('[', ']');
            var vectorTokens = param.Split(',');
            var vectorValues = vectorTokens.Select(token => float.Parse(token, CultureInfo.InvariantCulture.NumberFormat)).ToList();
            while (vectorValues.Count < 3)
                vectorValues.Add(0f);
            return new Vector3(vectorValues[0], vectorValues[1], vectorValues[2]);
        }

        var obj = s_GameObjects.FirstOrDefault(go => go.name == param);
        if (!obj)
            return Vector3.zero;
        return obj.transform.position;
    }

    static GameObject ObjectFromItem(SearchItem item)
    {
        var instanceID = Convert.ToInt32(item.id);
        var obj = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
        return obj;
    }

    static Texture2D GetThumbnailForGameObject(GameObject go)
    {
        var thumbnail = PrefabUtility.GetIconForGameObject(go);
        if (thumbnail)
            return thumbnail;
        return EditorGUIUtility.ObjectContent(go, go.GetType()).image as Texture2D;
    }

    static Texture2D GetAssetPreviewFromPath(string path, Vector2 previewSize, FetchPreviewOptions previewOptions)
    {
        var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path);
        if (obj == null)
            return null;
        var preview = AssetPreview.GetAssetPreview(obj);
        if (preview == null || previewOptions.HasFlag(FetchPreviewOptions.Large))
        {
            var largePreview = AssetPreview.GetMiniThumbnail(obj);
            if (preview == null || (largePreview != null && largePreview.width > preview.width))
                preview = largePreview;
        }
        return preview;
    }
}

静态变量

entrySeparatorsSeparators used to split an entry into indexable tokens.

静态函数

CreateGroupProviderCopy of a search provider to create a new group copy.
CreateQueryCreates a new search query.
CreateSceneResultCreates a search item compatible with the scene provider.
EnumerateAllQueriesEnumerate all user and project search queries.
FetchGameObjectsUtility function to fetch all the game objects in a particular scene.
FindQueryFind a given search query given its GUID.
FindShiftLeftVariationsExtract all variations on a word. As an example: the word hello would have the following variations: h, he, hel, hell, hello.
FormatBytesFormats a number into a file size in bytes string.
FormatCountFormats a number into a shorten number string.
FrameAssetFromPathPing an asset in the project browser.
GetAssetPathReturns the asset path of a search item if any.
GetAssetPreviewFromPathReturns a preview texture to be used in the search view.
GetAssetThumbnailFromPathReturns a thumbnail texture to be used in the search view.
GetHierarchyAssetPathGet the path of the scene (or prefab) containing a GameObject.
GetHierarchyPathGet the hierarchy path of a GameObject including the scene name if includeScene is set to true.
GetMainAssetInstanceIDReturns an asset instance ID.
GetMainWindowCenteredPositionReturns a UnityEngine.Rect to center a window on the main Unity Editor window.
GetObjectPathGet the path of a Unity Object. If it is a GameObject or a Component it is the . Else it is the asset name.
GetSceneObjectPreviewReturns a scene object preview to be used in the search view.
GetTransformPathFormat the pretty name of a Transform component by appending all the parent hierarchy names.
GetTypeIconReturns a thumbnail for a given type that can be displayed in a search view. See SearchProvider.fetchThumbnail.
MatchSearchGroupsHelper function to match a string against the SearchContext. This will try to match the search query against each token of content (similar to the AddComponent menu workflow).
OpenQueryOpen a search view for a given query.
PingAssetPing an object.
SelectMultipleItemsSelect and ping multiple objects in the Project Browser.
ShowColumnSelectorOpens an auxiliary column selector window to allow the user to search for a column to be added.
ShowIconPickerOpens a search picker to select an icon.
SplitCamelCaseTokenize a string each capital letter.
SplitEntryComponentsSplit an entry according to a specified list of separators.
SplitFileEntryComponentsSplit a file entry according to a list of separators and find all the variations on the entry name.
StartDragUtility function used to initiate a drag operation from a search view.
TryParseTry to parse an expression into a number.