SearchProvider manages search for specific types of items and manages all fields of a SearchItem such as thumbnails, descriptions, subfilters.
A first example that allows to search for specific prefabs and insert them in the scene.
using System.Collections.Generic; using UnityEditor; using UnityEditor.Search; using UnityEngine; static class Example_SearchProvider { internal static string id = "example_tree"; internal static string name = "example_Tree"; [SearchItemProvider] internal static SearchProvider CreateProvider() { return new SearchProvider(id, name) { filterId = "tree:", priority = 99999, // put example provider at a low priority fetchItems = (context, items, provider) => { // That provider searches for tree prefabs in the project var results = AssetDatabase.FindAssets("t:Prefab tree" + context.searchQuery); foreach (var guid in results) { items.Add(provider.CreateItem(context, AssetDatabase.GUIDToAssetPath(guid), null, null, null, null)); } return null; }, #pragma warning disable UNT0008 // Null propagation on Unity objects // Use fetch to load the asset asynchronously on display fetchThumbnail = (item, context) => AssetDatabase.GetCachedIcon(item.id) as Texture2D, fetchPreview = (item, context, size, options) => AssetDatabase.GetCachedIcon(item.id) as Texture2D, fetchLabel = (item, context) => AssetDatabase.LoadMainAssetAtPath(item.id)?.name, fetchDescription = (item, context) => AssetDatabase.LoadMainAssetAtPath(item.id)?.name, toObject = (item, type) => AssetDatabase.LoadMainAssetAtPath(item.id), #pragma warning restore UNT0008 // Null propagation on Unity objects // Shows handled actions in the preview inspector // Shows inspector view in the preview inspector (uses toObject) showDetailsOptions = ShowDetailsOptions.Inspector | ShowDetailsOptions.Actions, trackSelection = (item, context) => { var obj = AssetDatabase.LoadMainAssetAtPath(item.id); if (obj != null) EditorGUIUtility.PingObject(obj.GetInstanceID()); }, startDrag = (item, context) => { var obj = AssetDatabase.LoadMainAssetAtPath(item.id); if (obj != null) { DragAndDrop.PrepareStartDrag(); DragAndDrop.objectReferences = new Object[] { obj }; DragAndDrop.StartDrag(item.label); } } }; } [SearchActionsProvider] internal static IEnumerable<SearchAction> ActionHandlers() { return new[] { new SearchAction(id, "Insert tree", null, "Insert a single tree in scene") { handler = (item) => { InsertPrefab(item.id); } }, new SearchAction(id, "Insert forest", null, "Insert a forest in scene") { handler = (item) => { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { var instance = InsertPrefab(item.id); if (instance != null) instance.transform.Translate(i, 0, j); } } } } }; } private static GameObject InsertPrefab(string id) { return (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(AssetDatabase.GUIDToAssetPath(id)), Selection.activeGameObject != null ? Selection.activeGameObject.transform : null); } public static void Init() { for (int i = 0; i < 5; ++i) { var go = new GameObject(); PrefabUtility.SaveAsPrefabAsset(go, "Assets/tree" + i + ".prefab"); Object.DestroyImmediate(go); } SearchService.ShowContextual(id); } }
Another example that allows to search for lights and modify them. This provider uses another provider to get the lights.
using System; using System.Collections.Generic; using UnityEditor; using UnityEditor.Search; using UnityEngine; static class SearchProviderLights { static SearchProvider sceneProvider = null; static Texture2D lightTexture = EditorGUIUtility.FindTexture("Lighting"); [SearchItemProvider] internal static SearchProvider CreateProvider() { return new SearchProvider("example_lights", "example_Lights") { filterId = "z:", priority = 99999, // put example provider at a low priority fetchItems = (context, items, provider) => FetchItems(context, provider), showDetailsOptions = ShowDetailsOptions.Inspector, toObject = ToObject, onEnable = OnEnable, onDisable = OnDisable, // This provider can be used in the scene and hierarchy contextual search isEnabledForContextualSearch = () => IsFocusedWindowTypeName("SceneView") || IsFocusedWindowTypeName("SceneHierarchyWindow") }; } private static IEnumerable<SearchItem> FetchItems(SearchContext context, SearchProvider provider) { if (string.IsNullOrEmpty(context.searchQuery) || sceneProvider == null) yield break; using (var innerContext = SearchService.CreateContext(sceneProvider, "t:light " + context.searchQuery)) using (var results = SearchService.Request(innerContext)) { foreach (var r in results) { if (r != null) { yield return provider.CreateItem(context, r.id, r.GetLabel(innerContext, true), r.GetDescription(innerContext, true), lightTexture, null); } else { // ***IMPORTANT***: Make sure to yield so you do not block the main thread waiting for results. yield return null; } } } } private static void OnEnable() { sceneProvider = SearchService.GetProvider("scene"); } private static void OnDisable() { sceneProvider = null; } private static UnityEngine.Object ToObject(SearchItem item, Type type) { if (!(EditorUtility.InstanceIDToObject(int.Parse(item.id)) is GameObject light)) return null; return light.GetComponent<Light>(); } private static bool IsFocusedWindowTypeName(string focusWindowName) { return EditorWindow.focusedWindow != null && EditorWindow.focusedWindow.GetType().ToString().EndsWith("." + focusWindowName); } [MenuItem("Examples/SearchProvider/Show lights")] public static void ShowLights() { // Search for directional lights (lights with "directional" in their name) SearchService.ShowWindow(SearchService.CreateContext("z:directional")); } }
actions | Search provider actions. |
active | Indicates if the search provider is active or not. Inactive search providers are ignored by the search service. The active state can be toggled in the search settings. |
fetchColumns | Handler used to enumerate search columns to be used in the Search Table view. |
fetchDescription | Handler to provide an asynchronous description for an item. Is called when the item is about to be displayed. Allows a plugin provider to only fetch long descriptions when they are needed. |
fetchItems | MANDATORY: Handler to get items for a given search context. The return value is an object that can be of type IEnumerable or IEnumerator. The enumeration of those objects should return SearchItems. |
fetchLabel | Handler used to fetch and format the label of a search item. |
fetchPreview | Similar to fetchThumbnail, fetchPreview usually returns a bigger preview. The Search UI will progressively show one preview each frame, preventing the UI from blocking if many previews need to be generated at the same time. |
fetchPropositions | Handler used to enumerate search propositions when the user is using TAB to auto-complete a query. |
fetchThumbnail | Handler to provide an asynchronous thumbnail for an item. Is called when the item is about to be displayed. Compared to preview a thumbnail should be small and returned as fast as possible. Use fetchPreview if you want to generate a preview that is bigger and slower to return. Allows a plugin provider to only fetch/generate previews when they are needed. |
filterId | Text token used to "filter" by search provider (ex: "me:", "p:", "s:"). |
id | Search provider unique ID. |
isEnabledForContextualSearch | Called when search is invoked in "contextual mode". Returns true if the search provider is enabled for this search context. |
isExplicitProvider | This search provider is only active when specified explicitly using the filterId. |
name | Unique ID of the search provider. |
onDisable | Called when the SearchWindow is closed. Allows the search provider to release cached resources. |
onEnable | Called when the SearchWindow is opened. Allows the search provider to perform some caching. |
priority | Hint to sort the search provider. Affects the order of search results and the order in which search providers are shown in the FilterWindow. |
showDetails | Indicates if the search provider can show additional details or not. |
showDetailsOptions | Defines the details options to be shown. |
startDrag | If implemented, the item supports drag. It is up to the SearchProvider to properly set up the DragAndDrop manager. |
toObject | Returns any valid Unity object held by the search item. |
trackSelection | Called when the selection changed and can be tracked. |
SearchProvider | Create a new SearchProvider. |
CreateItem | Helper function to create a new search item for the current search provider. |