Search Unity

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

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

  1. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    565
    Why did it have to be me....I don't see it in the windows menu. Are you meaning the windows menu next to the help menu because it's not listed. I am using 2018.3.8f1.
     
  2. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    It is located there. If there are any error messages in the console, you must resolve those errors first.

    editor.png
     
    SilverStorm likes this.
  3. drambaldi

    drambaldi

    Joined:
    Aug 9, 2018
    Posts:
    4
    Hello, after the last update was working but today it stopped to give results (always no results found). There is a way to delete the cached data?
     
  4. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
  5. pixelknight

    pixelknight

    Joined:
    Jul 12, 2011
    Posts:
    88
    Hey, great work so far on the tool... can't wait to use it.

    I've got it on Unity version 2019.2.2 and seem to be getting a crash bug no matter what asset I'm trying to search in the project view. Is there a fix available?

    Thanks again for the hard work put into this so far!

    InvalidCastException: Specified cast is not valid.
    Model.Unit.Equals (System.Object obj) (at <8efbdbeaeed1474b83928e86de15dabc>:0)
    System.Collections.Generic.ObjectEqualityComparer`1[T].LastIndexOf (T[] array, T value, System.Int32 startIndex, System.Int32 count) (at <ad04dee02e7e4a85a1299c7ee81c79f6>:0)
    System.Array.LastIndexOfImpl[T] (T[] array, T value, System.Int32 startIndex, System.Int32 count) (at <ad04dee02e7e4a85a1299c7ee81c79f6>:0)
    System.Array.LastIndexOf[T] (T[] array, T value, System.Int32 startIndex, System.Int32 count) (at <ad04dee02e7e4a85a1299c7ee81c79f6>:0)
    System.Array.LastIndexOf[T] (T[] array, T value, System.Int32 startIndex) (at <ad04dee02e7e4a85a1299c7ee81c79f6>:0)
    System.Collections.Generic.Stack`1[T].Contains (T item) (at <376e8c39bbab4f1193a569c8dbe4305c>:0)
    AssetUsageDetectorNamespace.AssetUsageDetector.SearchObject (System.Object obj) (at Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:607)
     
    Last edited: Aug 29, 2019
  6. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    Thanks for reporting this. I am unable to tell why this exception isn't caught by this catch block. Regardless, can you try applying the following script modifications to your project?
     

    Attached Files:

  7. pixelknight

    pixelknight

    Joined:
    Jul 12, 2011
    Posts:
    88
    Super! Seems to be working great. Its already saving a ton of time.. some friends wonder why this kind of functionality isn't standard.

    Great work!
     
    yasirkula likes this.
  8. drambaldi

    drambaldi

    Joined:
    Aug 9, 2018
    Posts:
    4
    Thanks, but removing the cache did not solve the issue.
    Actually I have reverted to the old version without cache. (slower but works ...)

    Let me know if you need some tests with the new version. In production we keep the old version meanwhile.

    Best Regards
     
  9. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    I'm sorry to hear that. Can you tell what kind of a reference the current version of the plugin fails to find?
     
  10. drambaldi

    drambaldi

    Joined:
    Aug 9, 2018
    Posts:
    4
    Hello the asset was a Sprite linked directly in the Main scene and the issue is for sure related with the cache (old version works).

    The project is a production project with several branches and I switch branch quite often (may be related?). Strange thing: if I delete the cache nothing change.

    Let me know if you need some tests, in the meantime I am using the old one.
     
  11. josoka

    josoka

    Joined:
    Mar 22, 2019
    Posts:
    5
    THANK YOU

    you're a life saver!

    Just what I needed!
     
    yasirkula likes this.
  12. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
  13. dohaiha930

    dohaiha930

    Joined:
    Mar 27, 2018
    Posts:
    53
    Thank you so much @yasirkula, even after i buy some tool Finder with 15$, it's not better than your free asset. It's accurate and find what ever i want, just a little bit longer with huge project.
     
    yasirkula likes this.
  14. drambaldi

    drambaldi

    Joined:
    Aug 9, 2018
    Posts:
    4
    Thanks for this amazing open source asset!

    I am testing version 1.5.6 and everything work correctly with the cache!

    I have always strange issue because I work on a legacy project that is up from 2016 and there is a lot of legacy-old code unremoved ...

    I have noticed this BUG, ONLY for one of my sprite (still investigating the issue to find the particlesystem that raise the error):

    STEPS TO REPRODUCE
    - Search for a sprite with Search properties public and Non-public with Scenes in build settings
    - Select Include non-serializable fields and properties in search (slower search)
    - The Asset Usage detector fail with ERROR:


    NullReferenceException: Do not create your own module instances, get them from a ParticleSystem instance
    Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.


    Staktrace


    rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.","NullReferenceException: Do not create your own module instances, get them from a ParticleSystem instance
    Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.","ParticleSystem+TextureSheetAnimationModule.get_frameOverTime() /Users/builduser/buildslave/unity/build/artifacts/generated/bindings_old/common/ParticleSystem/ParticleSystemBindings.gen.cs:2681
    MonoMethod.Invoke() /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222
    MonoMethod.Invoke() /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:232
    MonoProperty.GetValue() /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoProperty.cs:297
    MonoProperty.GetValue() /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoProperty.cs:283
    Utilities+<CreateGetter>c__AnonStorey0.<>m__0() Assets/Plugins/AssetUsageDetector/Editor/Utilities.cs:337
    VariableGetterHolder.Get() Assets/Plugins/AssetUsageDetector/Editor/VariableGetter.cs:35
    AssetUsageDetector.SearchFieldsAndPropertiesOf() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:1113
    AssetUsageDetector.SearchObject() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:808
    AssetUsageDetector.SearchFieldsAndPropertiesOf() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:1118
    AssetUsageDetector.SearchComponent() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:918
    AssetUsageDetector.SearchObject() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:789
    AssetUsageDetector.SearchGameObject() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:850
    AssetUsageDetector.SearchObject() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:787
    AssetUsageDetector.BeginSearchObject() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:727
    AssetUsageDetector.SearchGameObjectRecursively() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:712
    AssetUsageDetector.SearchGameObjectRecursively() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:716
    AssetUsageDetector.SearchGameObjectRecursively() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:716
    AssetUsageDetector.SearchGameObjectRecursively() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:716
    AssetUsageDetector.SearchGameObjectRecursively() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:716
    AssetUsageDetector.SearchGameObjectRecursively() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:716
    AssetUsageDetector.SearchGameObjectRecursively() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:716
    AssetUsageDetector.SearchGameObjectRecursively() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:716
    AssetUsageDetector.SearchGameObjectRecursively() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:716
    AssetUsageDetector.SearchGameObjectRecursively() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:716
    AssetUsageDetector.SearchScene() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:678
    AssetUsageDetector.Run() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:544
    Debug.LogException()
    AssetUsageDetector.Run() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs:573
    AssetUsageDetectorWindow.InitiateSearch() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetectorWindow.cs:529
    AssetUsageDetectorWindow.OnGUI() Assets/Plugins/AssetUsageDetector/Editor/AssetUsageDetectorWindow.cs:410
    GUIUtility.ProcessEvent()"


    Best Regards
    Davide
     
    yasirkula likes this.
  15. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    Apparently, this happens when there is a variable of type ParticleSystem.TextureSheetAnimationModule in a class. Although I can prevent this issue from occurring via a hacky tweak, it would have a negative impact in the overall search performance. So I won't be implementing this fix. But we can let AssetUsageDetector continue the search despite this harmless error. It just a matter of changing VariableGetterHolder.Get function as follows:

    Code (CSharp):
    1. public object Get( object obj )
    2. {
    3.     try
    4.     {
    5.         return getter( obj );
    6.     }
    7.     catch( Exception e )
    8.     {
    9.         Debug.LogException( e );
    10.         return null;
    11.     }
    12. }
    This change will be included in the next release, as well.
     
    mattxreality likes this.
  16. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
  17. iLoveGamesDeveloper

    iLoveGamesDeveloper

    Joined:
    Aug 8, 2019
    Posts:
    1
    Hi @yasirkula, this is amazing. I'm not sure why Unity hasn't developed their internal asset search (even their Find Reference in Scenes seems broken). Thanks a lot for this!
     
    yasirkula likes this.
  18. rafaelrbenavent

    rafaelrbenavent

    Joined:
    Sep 29, 2018
    Posts:
    8
    I'm getting a stack overflow using this. And then my Unity crashes.
    Also, the panel says "ERROR: Search was interrupted, check the logs" but the documentation doesn't mention where the logs are stored (unless it's referring to the Console/Unity logs).
     
    Last edited: Jan 15, 2020
  19. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    Yes, it is Unity's logs in Console. When does Unity crash? A few seconds after seeing that message? Are you using the latest version of the plugin? There has been a few bugfixes for this issue.
     
  20. rafaelrbenavent

    rafaelrbenavent

    Joined:
    Sep 29, 2018
    Posts:
    8
    Yep, just download it from the Asset Store yesterday. Unity doesn't crash it just freezes.
    Here is an error log:

     
  21. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    Can you add this function to line 1511 and see what it outputs:
    Debug.Log( assetPath + " " + dependencies[i] );
     
  22. rafaelrbenavent

    rafaelrbenavent

    Joined:
    Sep 29, 2018
    Posts:
    8
    Sorry but stack overflow + debug.log is not a good combo and ended up having to restart Unity. I think it happened on a terrain object or terrain data.
     
  23. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    I've been trying to reproduce the issue on 2019.1 and 5.6 but couldn't succeed. Which Unity version are you using? Are you searching while in Play mode? If possible, could you replace
    Debug.Log( assetPath + " " + dependencies[i] );
    with
    System.IO.File.AppendAllText( @"C:\Users\USERNAME\Desktop\log.txt", assetPath + " " + dependencies[i] + "\n" );
    ? Pinpointing the issue could really help here.
     
  24. rafaelrbenavent

    rafaelrbenavent

    Joined:
    Sep 29, 2018
    Posts:
    8
    Sorry, I was using 2019.2.3f1. Searching in Edit mode. I already deleted a bunch of objects, so I can't really be of much more help unfortunately.
     
    yasirkula likes this.
  25. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    I've released a new version on GitHub. In addition to some other improvements, if an infinite loop is detected inside AssetHasAnyReference, plugin will now output some useful information to help debug the issue instead of raising a StackOverflowException.
     
    rafaelrbenavent likes this.
  26. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    246
    I really love this asset. It works better than find usages in some IDEs, where there is usually well established syntactic data model to exploit. Bravo.

    If it were me, I would take down the promise that it will always be free. Anybody who gets it free now can keep getting it free even if you decide to charge new customers. Why limit your future options that way?

    Anyway, very nice asset.
     
    yasirkula likes this.
  27. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    Your support is much appreciated, thanks!
     
  28. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    246
    I will point out that it seems like it will find a reference to an asset if any asset with that same name has a reference. I fixed that by ensuring that the asset path was used as the object hash for an object that is also an asset.
     
  29. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    I've created a test case as follows:

    test.png

    Searching for references of the Test/Subfolder/Cube.prefab's material only yields that prefab for me, not Test/Cube.prefab. Maybe in your case, the other asset with the same name had some other connection to the searched asset?
     
  30. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    246
    No. I verified there were no connections. When I went to where the tool said there was a connection, it was pointed toward the asset with the same name, not the one I was searching for.

    Heres a more detailed version of the case:
    1. Two folders. Each has a PNG asset with the exact same name. The only difference is that one of them is 128x128 and the other is 512x512.
    2. Have a prefab with a reference to the 512x512 version.
    3. Search for everything under the first folder (the 128x128).
    4. It says it found a reference in the aforementioned asset.
    5. Click into the asset and see that the aforementioned reference is the 512x512 version of the image.
     
  31. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    I've created the following folder structure:

    Test2.png

    Assigned these textures to asset bundles to see if it makes any difference:

    Test3.png
    Test4.png

    My material uses _Test1/ZomBunnyDiffuse texture. Searching for references of _Test2 folder doesn't yield any results for me.

    May I ask which Unity version you are using? Are you using AssetBundles or Addressables systems? I suspect that the two textures in your case have the same "Instance ID", you can check if this is the case by switching to Debug mode in Inspector (right click Inspector tab) and inspecting the textures. Are you using any plugins that possibly might alter these textures' instanceIDs?

    Thanks for the valuable feedback!
     
  32. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    246
    I was using 2019.3.0f6. Looking for the instance ID would require my spelunking my source-control history, as the purpose of finding usages (in my case) was to delete the low-resolution assets.

    I'm skeptical that they have the instance ID. In the asset I was using, the 128x128 images came across as proper assets but the 512x512 assets were just in a .zip file full of PNGs. Unity had to generate new instance IDs when I dumped the images into a subfolder of Assets.

    I could see in the code that the hash was being generated from the name and when I changed it to be based on the asset path, the problem went away.

    Before:

    Code (CSharp):
    1. public static string Hash(this object obj)
    2. {
    3.   if (obj is Object)
    4.     return obj.GetHashCode().ToString();
    5.  
    6.   return obj.GetHashCode() + obj.GetType().Name;
    7. }
    8.  
    After:

    Code (CSharp):
    1. public static string Hash(this object obj)
    2. {
    3.   if (obj is Asset a)
    4.     return "assetpath:" + a.assetPath;
    5.  
    6.   if (obj is Object)
    7.     return obj.GetHashCode().ToString();
    8.  
    9.   return obj.GetHashCode() + obj.GetType().Name;
    10. }
    11.  
    I do not (presently) use Asset Bundles. Nor is anything an Addressable..
     
  33. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    246
    I suppose another factor that may or may not matter is that the assets in question were referenced from overrides in a nested prefab.
     
  34. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    1,295
    Object.GetHashCode returns the object's instanceID which should be unique per each object (it isn't affected by name). So there can be two reasons for this bug to occur:

    1. AssetUsageDetector actually did find a reference to the 512x512 image (so it didn't confuse it with the 128x128 image) but it wasn't a very obvious reference. I wish I could've seen the search results screen in Full path drawing mode but I guess it is too late for that now.
    2. The comments inside GetHashCode mention edge cases:
    It's actually possible to have multiple c# objects pointing to the same c++ object in some edge cases
    . An edge case occurred in your case, resulting in duplicate instanceIDs.

    I really don't think it was the 2nd case since googling for similar issues doesn't return anything. But if it was the 2nd case, I'd prefer to first understand when these edge cases occur, see if it can be prevented in a better way and only then use asset path as hash if necessary.

    Thanks for providing me with details about this bug. Let's see if someone else stumbles upon this bug and see if they also suffer from the 2nd case.
     
  35. NicoMim

    NicoMim

    Joined:
    Feb 11, 2019
    Posts:
    1
    Saved me a lot of time, thanks you :D
     
    yasirkula likes this.
unityunity