Hi! Thank you very much for this.
- I’m using Unity 6000.0.30.
- I am using the SearchItemProviderAttribute to register the SearchProvider, as the docs suggest. Is there another way to do it?
- I’d need to share a lot of code for the actual provider I made to make sense. That said, I tried with a plain, barebones provider and onDisable still doesn’t run there:
public class TestSearchProvider : SearchProvider
{
public TestSearchProvider() : base("testprovider", "Test Search Provider")
{
fetchItems = (ctx, items, provider) => FetchItems(ctx, provider);
onEnable = () => Debug.Log("Enabled");
// "Disabled" is never printed.
onDisable = () => Debug.Log("Disabled");
}
[SearchItemProvider]
public static SearchProvider CreateProvider()
{
return new TestSearchProvider();
}
private IEnumerable<SearchItem> FetchItems(SearchContext ctx, SearchProvider provider)
{
for (int i = 0; i < 10; i++)
{
string text = "Test Item" + i.ToString();
yield return provider.CreateItem(ctx, text, text, null, null, null);
}
}
}
On the last question:
I’m making an ecosystem of systems I use into a plugin for Unity. It uses assets as the main way to modularize game logic. Some these assets are graphs: Behavior Trees, State Machine, and Utility Theory graphs (I’ll probably only release BTs and SMs initially). I have a way to look for references to other assets, and to some int ids in these graphs. It makes things easier to debug at scale; there are so many modularization opportunities with these graphs that being able to pin point which element of which graph is referencing something is very useful.
I decided to remake my search system into a Search Provider for multiple reasons:
-
One of my goals is to make my stuff play well with the common Editor UX. Users are probably more familiar with the Search Window than with any custom UI I make. It does have some quirks and a couple of bugs, but it’s not so bad that it isn’t usable. I find it very useful myself as a normal user.
-
I can use the same filter words that other Unity providers use. So, for example, I can use “ref=” to allow users to search inside graphs at the same time they search in the Scene and in other assets.
-
It makes it very easy for things to scale with the fetch callbacks. I can provide delayed search results by using an IEnumerable
for fetchItems
, and then I can delay the results’ descriptions, labels, icons, etc.
-
The API is very extensive, and there’s a lot of documentation content. I found it relatively easy to use it. I may have used my own thing instead of this API if it wasn’t so easy to make something with it.
I’d also say that a bit of clean up could go a long way with the Search API. There are some bugs, like the ones I mentioned. Another one I’m remembering now is that dragging an item that supports dragging (e.g. a Scene result) when in List View mode, often triggers a "Starting multiple Drags. You can only start one drag at a time!"
error.
There’s a good amount of things in the API that are no longer being used or that don’t do what is said in the docs. For example:
- context.empty no longer returns true when there’s only a provider id in the search text.
- The saveFilters param is no longer used in SearchService.ShowWindow.
- There are exposed types that were clearly meant to be internal, or at least they should have a different name. For example, there’s an ObjectField that collides with UITK’s own ObjectField. That ObjectField in particular is kind of bothersome when writing custom UITK code for columns, or when triggering the Search API from other UITK elements.
- There are more cases like these, I’m only writing some that I remember now.
All in all, though, this Search API and tools are awesome. Really useful, very nice idea. Congratulations to the team. I hope the higher ups at Unity can appreciate the importance of tools like these.
Thank you! 
EDIT
About solving the onDisable question at hand. By now, after learning a lot more while finishing my provider, I’m almost sure this is a bug on Unity’s side. I think I can survive without it being fixed. I’m already clearing my cache whenever I detect a change, either through Undo callbacks, asset postprocessor, or EditorApplication.projectChanged. In practice, I think cache cleaning is triggered enough for most use cases. If it can be fixed, or if there’s a work around, I’d still appreciate it, but it’s not blocking my development anymore.