yasirkula / UnityAssetUsageDetector

Find usages of the selected asset(s) and/or Object(s) in your Unity project, i.e. list the objects that refer to them
MIT License
1.74k stars 118 forks source link

Search fields of BaseType and search all fields marked UnityEngine.SerializeField. #2

Closed TimmermanV closed 6 years ago

TimmermanV commented 6 years ago

Hi!

Thanks for UnityAssetUsageDetector. It's a very useful piece of code. UnityAssetUsageDetector wasn't detecting some references in my project, so I tried making some changes to improve what kind of references it can find. I basically changed 2 things:

With these two changes I am able to find references in Paradoxnotion Behavior Trees and FSMs. (a Unity editor extension)

Note that I have never used this feature on github before, so please give me some feedback if you think I could have done things differently.

Thanks, Tim

yasirkula commented 6 years ago

Hello Tim,

Thank you for your contribution :) I really appreciate it. I was aware that private variables in base classes were not searched by my extension, as they are not returned by Type.GetFields method. I thought that a solution like yours would dramatically increase the search time but maybe I was wrong. I will give your solution a shot.

However, I just want to ask if "IsSerializable now returns true for any field marked with attribute UnityEngine.SerializeField." affected your search results in any way. Because marking variables with [SerializeField] does not always work (e.g. dictionaries) and I am unsure about whether this tweak did any difference or not.

TimmermanV commented 6 years ago

Thanks for your feedback. I must admit I'm much more proficient in writing C++ than I am writing C#. Especially when it comes to reflection. Using the VS debugger attached to Unity, I found that the AssetUsageDetector did not search the private fields and I found some code here https://stackoverflow.com/questions/1155529/not-getting-fields-from-gettype-getfields-with-bindingflag-default that I mostly copy/pasted. :) I did try to copy your code style though, but I'm not sure it's the most efficient solution. Perhaps using that IEnumerable based solution is faster? (see link) Could that work on Unity's version of C#? If it ends up searching too many paths, perhaps it could stop recursion earlier (before reaching BaseType null). Or perhaps searching private fields could be optional.

Anyway, I needed both these changes to find the references I was looking for. The asset references I want to find are in a private field of a base class of certain MonoBehavior derived classes. They are in a private List, marked [SerializeField]. The current code in IsSerializable allows for List<> and it also passes the next test, as the field is marked [SerializeField]. However, UnityEngine.Object is not marked [System.Serializable], so the last test in IsSerializable fails and it ends up skipping this field.

yasirkula commented 6 years ago

I've just updated the code. Private variables are now included in search (in a more performant way). I've also fixed the List<Object> issue correctly. Let me know if the problems persist.

TimmermanV commented 6 years ago

I have integrated the updated code into my project and it seems to be working. Thanks!