UnityAssetUsageDetector icon indicating copy to clipboard operation
UnityAssetUsageDetector copied to clipboard

Feature request: Search for direct references only

Open detzt opened this issue 1 year ago • 8 comments

I would like to have a search setting that excludes indirect references. I.e. when object A is used in prefab P and then both of them are used a couple of times in a scene and I search for A, only show where the scene directly references A and not where it indirectly references A only through the instances of P. (Include of course the one reference in P itself).

There is the setting "Hide redundant prefab variant links" and this works for excluding an unmodifying variant V of P, but it still shows instances of V or P in scenes when searching for A. And there are situations in which this is the desired behavior, so it should be a separate setting.


Some use cases:

  • Let's say a Material is used in many prefabs (and those prefabs are used in scenes), but it is also used as override for some special objects in a scene to give them a different material. Now I want to find these overrides. They do show up in the search results, but are mixed in with all the prefab instances. By searching for all materials in that way I could also find all of the special modified objects.
  • Let's say for refactoring a script I need to make an adjustment in all places where that MonoBehaviour is used. After adjusting it in the prefabs, it is already done for all prefab instances. However, I still need to adjust it in all places where a scene GameObject uses that script directly.
  • Let's say I want to modify a texture but first make sure to know which objects would be impacted by a change. Searching for references shows it's used in a door prefab and hundred times in a scene. Are all hundred scene references doors or is there maybe another object in the scene that uses the texture?

Bonus points for still including instances of P that contain a modification on A, but I would be fine with whatever you prefer / is easier to implement. I think this boils down to showing exactly the places where the GUID of the searched object is actually written in a file?

And thank you for this amazing tool, it has made my life and work a lot easier!

detzt avatar Oct 21 '24 01:10 detzt

With the current implementation, I believe you can right click the scene, select "Expand Direct References Only" and then ignore the lines that don't have a green tint to their left (green tint indicates that the object resides in the scene). If you wish, you could then select the non-green lines and remove them via Delete.

https://github.com/user-attachments/assets/18986b2b-d99b-4c4a-8665-ba986ba4c58b

yasirkula avatar Oct 22 '24 19:10 yasirkula

Thank you for the quick response! I didn't know "Expand Direct References Only" and "Expand Main References Only" exist. However, in all cases I tested they collapsed all search results without exceptions and all objects have a green tint on it.

detzt avatar Oct 23 '24 01:10 detzt

For "scene object->prefab->searched reference" chains, prefab shouldn't be tinted green (inside scene search results). I'm surprised TBH.

yasirkula avatar Oct 23 '24 11:10 yasirkula

For that setup as well: All search results are tinted green.

detzt avatar Oct 23 '24 12:10 detzt

Could you create a small repro case so that I can investigate it further?

yasirkula avatar Oct 23 '24 13:10 yasirkula

Here on that branch I created a reproduction setup to showcase it: https://github.com/detzt/BugReporting/tree/bugs/direct-references

When you search for references of the Blue or Green material, I with to distinguish between direct references in the scene (the quad objects that have "in scene" in their name) and indirect references (the cubes that are simply named "Model").

Besides the names that are explicitly set for this example, the entries in the search results are indistinguishable. Also note that I added the DummyScript to give most of the search results a foldout. When I search in my other projects, many results are without foldouts, so "expand/collapse only xxx" is not great to distinguish groups.

I hope this illustrates the issue I'm having.

detzt avatar Oct 23 '24 19:10 detzt

I see what you mean. I'll experiment on it.

yasirkula avatar Oct 26 '24 14:10 yasirkula

Thank you :)

detzt avatar Oct 26 '24 14:10 detzt

I've added "Hide non-overridden prefab variables in scenes" option to achieve this. In the future, I'm planning to experiment on a similar filtering for when a C# script's or prefab's usages are searched.

yasirkula avatar Nov 03 '24 09:11 yasirkula

It works flawlessly, thank you!

detzt avatar Nov 07 '24 23:11 detzt

I've added support for C# script and prefab usages. Before releasing it, I'm trying to make sure that it has a good user experience. This new feature means that:

  • While searching for DummyScript.cs' references, Prefab will show up but Variant or Nested Prefab won't. In the scene, only Plain Object will show up
  • While searching for Prefab's references, Variant will show up (it's a variant of Prefab directly) but Nested Prefab won't (it doesn't use Prefab directly). In the scene, neither Variants nor Nested Prefabs will show up (none of them are instances of Prefab)

Tooltips:

image

image

The new warning:

image

What do you think about this change? Feel free to express your concerns or suggest modifications.

yasirkula avatar Dec 06 '24 15:12 yasirkula

Looks good to me in general 👍🏼

When any overrides are present on objects that would otherwise be hidden, they are still showing up in the search results, right? E.g. in the second tooltip scenario, if Healthbar.maxHealth would be overridden in one of the scene instances, that scene instance would not get hidden?

When Prefab A is nested in Prefab B and I search for A, it shows its occurrence in B and any direct instances of A in any scenes, but instances of B are hidden, correct?

Good idea to display information about the hidden search results. Maybe "... were excluded." fits better than "... were skipped."? The yellow warning sign is a bit too much attention grabbing for something that will show up in many regular searches with expected results, so I would suggest the white info icon instead.

detzt avatar Dec 06 '24 16:12 detzt

if Healthbar.maxHealth would be overridden in one of the scene instances, that scene instance would not get hidden

Right now, this isn't the case. If I search for Healthbar prefab's usages, it won't show up in the scene regardless of whether or not it's modified in any way. The only case where variable overrides make a difference is the original case that we've resolved last month: if the searched object is found in an overridden prefab variable, then that variable will show up.

I actually thought about your suggestion while developing this feature. I think the desired behaviour mostly depends on the user. How would you suggest I go about this?

When Prefab A is nested in Prefab B and I search for A, it shows its occurrence in B and any direct instances of A in any scenes, but instances of B are hidden, correct?

Yes.

Maybe "... were excluded." fits better than "... were skipped."

Your suggestion sounds good to me.

The yellow warning sign is a bit too much attention grabbing so I would suggest the white info icon instead.

You are not wrong; though I actually wanted it to be eye catching because I think if a user enables this feature but then forgets about it, it could have a very negative impact on their future searches. For example, Prefab A won't show up in the scene at all even though it exists as a child of Prefab B in the scene. I wanted the user to be always aware of this setting. But I'll give white info icon a chance.

yasirkula avatar Dec 06 '24 17:12 yasirkula

Nice :)

For me personally, the meaning / use case of the two setting states are as follows: Unchecked: Show me all places where this object exists. Checked: Hide all search results where this object only happens to be because it is part of a larger object, but nobody really cares about it. I.e. only show me the places where something interacts with this object.

From that point of view, I would say the HealthBar instance should show up when it has overrides on it. E.g. when I want to modify or remove the HealthBar prefab, I only have to pay attention where it is referenced directly (Player prefab or HealthBar variants) and also consider the implications on places that have overrides on it. For the places where no overrides are present, I can assume they only care about the Player instance.

What about searching for the HealthBar script? Let's say there's a HealthBar script directly on the HealthBar prefab and it has a maxHealth SerializedField. When a scene has an override on maxHealth in a Player instance, would that show up when searching for the script?

detzt avatar Dec 07 '24 00:12 detzt

I'll try doing it the way you've suggested, thanks again. I'll first see if I can quickly find if a Component or GameObject has any overrides (ideally, I wouldn't want to slow down the search for this feature).

What about searching for the HealthBar script?

Right now, components are hidden regardless of overrides, same as GameObjects.

yasirkula avatar Dec 08 '24 20:12 yasirkula

Done! While deciding if a prefab instance has any overrides, I've decided to exclude just the following properties:

  • Target prefab instance's Transform properties (e.g. Position, Rotation, Scale) because it's common for prefab instances to have different Transform values
  • Target prefab instance's GameObject properties (e.g. Tag, Layer, IsActive, IsStatic) mostly because it's faster to do so. I'd skip the IsActive property no matter what, so if I were to take the other properties into account, I'd have to iterate over all of them via SerializedProperty and exclude IsActive by name. I've decided that those variables aren't crucial in determining whether or not the prefab instance has any overrides

Do note that by "target prefab instance", I mean the Healthbar child object of the Player prefab instance (in this scenario, we're searching for Healthbar prefab's references). If Healthbar instance has any children, they are checked without any exclusions. These exclusions apply only to the root (Healthbar instance).

yasirkula avatar Dec 10 '24 17:12 yasirkula

Nice 👍🏼 Yes it is a good thought to ignore all of the Transform and GameObject overrides.

detzt avatar Dec 10 '24 19:12 detzt