If I use SearchService.Request with SearchFlags.Synchronous after script recompilation/domain reload, it does not find any results. If I do another run, suddenly it finds all results correctly.
If I use SearchService without SearchFlags.Synchronous after script recompilation/domain reload, everything works fine immediately.
This behaviour is 100% consitent and replicable, Unity 2022.3.0
Or am I missing something? This is the query I am running with Dependency index turned on:
var results = SearchService.Request($"ref={assetPath}", SearchFlags.Synchronous).Fetch()
First: kudos for using Search Expression (any expression using bracket {}). This is a our most advance workflow
Second: Synchronous flag works when Asset Provider do not use threaded operations. A lot of the Search Expression is done in threaded hence why it might not work. That said, I will test your query and investigate why it failed.
Third: The whole search infrastructure is based on asynchronicity. I would suggest you refrain to use the Synchronous flag (it is more of a legacy flag).
Thanks for the reply, I solved this by using async variant. However I have one search utility that does a search for a set of assets (all of them usually) and using async variant only does 1 search per editor update/frame so it’s a lot slower. I solved it with awaiting one async “test” search and after that I do sync search for all assets - works like a charm.
Is there a better solution? Moving to background thread does not work, maybe specifying the set of assets directly in search expression?
Just few days ago I discovered your github repo Search Extensions and Dependency Viewer so I will be studying your implementation. I have some questions/feature request about that but I will create separate thread for those
Hi! Can you explain a little the context around the call to SearchService.Request? Is it called in a OnAfterAssemblyReload or triggered manually sometime after? I’m asking because if this is called very early and the script compilation affected the indexes, those indexes might not be ready at that point and the Asset Provider just bails out if we are in synchronous mode.
The way it works is that each providers have 50ms to fetch some results. If search is not done after 50ms then we wait until next frame to continue. Depending on the time it takes to fetch the results, you might get more or you might get less each frame. Something I’m thinking that might be worth looking into for us is to provide a SearchService.Request overload where users could control the iteration and not rely on Editor Update to get results (you would potentially need to yield some frame to make sure you are not blocking the editor while waiting for indexes to be ready for example), but the control of how much time is spent fetching the results would be in the hands of the users. Looking at the SearchService.Request overload that returns an ISearchList, one could assume that it is the case already, but in reality the list yields null while waiting for more items that would come on the next frame.
Hi, it is triggered only manually, certainly not at any unusual editor time/event. The tool basically searches for unused assets.
I had my own implementation that crawled files for GUIDs and such and could run on a background thread. I decided that is time to switch to much faster Unity’s own solution as any caching and advanced optimization techniques were just out of time scope for me.
However the async variant of Unity Search can’t run on background thread and must yield to the editor from time to time (as you wrote). Which hinders the speed of execution because of timing and I ended up with slower search of unused assets then my own, because when I have 10 000 assets that’s 10 000 searches which is 10 000 frames. So the sync variant came to the rescue (I don’t really mind the Editor freeze for a few seconds, I do this complete sweep once in a month maybe), however I stumbled upon the issue described in the first post (and solved it as described in the second).
There is a similar and I think related issue which is discussed here
Hi! Thanks for the clarification. If the search is done long after the indexes are done reindexing, and the search doesn’t yield any result in synchronous mode then yeah there is an issue. We will investigate. Thanks for all your investigations and feedback, it is much appreciated.
If I understand correctly, you are trying to find all assets that are not referenced? Do you have a specific list of assets that you check, or do you want to find all assets that are unused? Maybe this query could help speed things up (one query for all assets vs 10000 different queries, if that’s not the case then disregard this) where{select{a:assets, $fileName, count{ref=$id} as Refs}, p(Refs)=0}
This will look for all assets in the project, count the result for each ref=$id where “$id” is the filename of the assets, and return those that have a count of 0. This could be tweaked for a specific index by changing “a:assets” to “a:MyIndex” to further refine the search.
This only works if you want to search for all assets or assets in a specific index. For a specific list of assets, you could try with the following: where{select{{name=name1.ext dir=dir1, name=name2.ext dir=dir2, ...etc.}, $fileName, count{ref=$id} as Refs}, p(Refs)=0}
We don’t have a filter to get an asset from a complete file path, so you have to split your paths into filenames and directories, but this should let you specify a list of assets to tests.
Sometimes I sweep all the assets, but usually some subfolder e.g. Sprites when trying to reduce memory usage and clean up atlases etc.
Thanks this could help me to improve my tools. I suspected that this should be possible:
I bet it’s even mentioned somewhere in the documentation, but docs are a bit fragmented (old and new unity doc sites, quicksearch package and integrated package…) I must have overlooked it.
Filter with a complete filepath would be nice, but as it can be scripted I can live with that. I have now switched over to UnitySearch and the tools are working good enough. I will be watching the improvements of UnitySearch and improving my tools along the way.
I am running into the same issue using Unity 2023.3.0b7.
I have a manually triggered (using [ContextMenu("<action>")]) synchronous method containing the following request (my actual request is slightly more complex, but this is enough to reproduce the problem):
using SearchContext context = SearchService.CreateContext("asset", "p: t:Prefab");
foreach (SearchItem result in SearchService.Request(context, SearchFlags.Synchronous).Fetch())
After recompiling some code, the first time I manually run it, it finds 0 results, any following run properly finds the results.
Making this method asynchronous is neither practical nor useful to me (the use case is rendering icons for prefabs using the currently opened scene).