Search Unity

  1. Get the latest news, tutorials and offers directly to your inbox with our newsletters. Sign up now.
    Dismiss Notice

Asset Usage Detector - Find references to an asset/object [Open Source]

Discussion in 'Immediate Mode GUI (IMGUI)' started by yasirkula, May 31, 2016.

  1. KenDots

    KenDots

    Joined:
    May 26, 2020
    Posts:
    2
    Hello!

    Thanks a lot for this tool, it has been very helpful! I wrote a simple script that calls your tool to help me find assets that have no references. In my case, the goal is to find sprites that have sprite packing tags (we are using legacy sprite packer) but are not actually referenced in any scenes/prefabs in the project.

    I didn't see any easy way to get this info, so my script does a single search for each sprite in our project, which takes a very long time. I was wondering if I was missing an easier way to accomplish this. Here is my script:

    Code (CSharp):
    1.        
    2.         void FindUnusedTexturesWithTag()
    3.         {
    4.             string[] textureGUIDs = AssetDatabase.FindAssets("t:Texture");
    5.  
    6.             StringBuilder sb = new StringBuilder();
    7.             AssetUsageDetector assetUsageDetector = new AssetUsageDetector();
    8.  
    9.             foreach (string textureGUID in textureGUIDs)
    10.             {
    11.                 string texturePath = AssetDatabase.GUIDToAssetPath(textureGUID);
    12.                 AssetImporter assetImporter = AssetImporter.GetAtPath(texturePath);
    13.                 TextureImporter textureImporter = assetImporter as TextureImporter;
    14.  
    15.                 if (textureImporter == null) //could be a NativeAssetImporter
    16.                 {
    17.                     continue;
    18.                 }
    19.  
    20.                 if (!string.IsNullOrEmpty(textureImporter.spritePackingTag))
    21.                 {
    22.                     Texture texture = AssetDatabase.LoadAssetAtPath<Texture>(texturePath);
    23.  
    24.                     Object obj = texture;
    25.                     SearchResult searchResult = assetUsageDetector.Run(new AssetUsageDetector.Parameters()
    26.                     {
    27.                         objectsToSearch = new ObjectToSearchEnumerator( new List<ObjectToSearch>(new ObjectToSearch[] {new ObjectToSearch(obj)}) ).ToArray(),
    28.                         searchInScenes = SceneSearchMode.ScenesInBuildSettingsTickedOnly,
    29.                         searchInAssetsFolder = true,
    30.                         searchInAssetsSubset = null,
    31.                         excludedAssetsFromSearch = null,
    32.                         dontSearchInSourceAssets = false,
    33.                         excludedScenesFromSearch =  null,
    34.                         lazySceneSearch = false,
    35.                         noAssetDatabaseChanges = true,
    36.                         showDetailedProgressBar = false
    37.                     });
    38.  
    39.                     if (searchResult.NumberOfGroups <= 0)
    40.                     {
    41.                         Debug.Log(texturePath + " Not Referenced!");
    42.                         sb.AppendLine(texturePath + " Not Referenced!");
    43.                     }
    44.                     else
    45.                     {
    46.                         Debug.Log(texturePath);
    47.                     }
    48.                 }
    49.             }
    50.  
    51.             Debug.Log(sb.ToString());
    52.  
    53.             string tempPath = FileUtil.GetUniqueTempPathInProject();
    54.             StreamWriter writer = new StreamWriter(tempPath);
    55.             writer.Write(sb);
    56.             writer.Close();
    57.             UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(tempPath, 1);
    58.         }
    Any thoughts? It seems like the most obvious way to improve this is to search for many assets at once, but if I did that, I didn't really see a clear way to determine that a particular asset came back with no references. I had trouble figuring out how I would correlate a `SearchResult` (or lack of one) to a particular asset I searched.
     
  2. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,086
    AssetUsageDetector doesn't just say "Sprite is referenced from Scene A", it says "Sprite is referenced from object B's C variable in Scene A", that's why it is slower. But you don't need such detailed information. Searching all sprites at once would surely help; the returned SearchResult is a graph split into multiple groups (scenes, Assets folder, etc.). You'd have to traverse every node in that graph and mark the sprites that you encountered as used.

    A much better solution in your case would be to use Unity's AssetDatabase.GetDependencies function. AssetUsageDetector uses it to determine if a searched object is used in Scene A and only then it searches that scene in detail. You can simply iterate over each asset in your project (AssetDatabase.GetAllAssets, excluding your sprites), get its dependencies and mark any sprites that these dependencies point to.
     
    KenDots likes this.
  3. Noa3

    Noa3

    Joined:
    May 29, 2012
    Posts:
    81
    Thank you for the Tool!
    it helps me to understand a project from a Different Company really fast
     
    Last edited: Oct 24, 2020
    MarcSpraragen and yasirkula like this.
  4. florinel2102

    florinel2102

    Joined:
    May 21, 2019
    Posts:
    47
    Thanks a lot ! :)
     
    yasirkula likes this.
unityunity