Skip to content

Commit 8072530

Browse files
committed
Added experimental Addressables support (requires manual modifications) (closed #29)
1 parent 28a73e2 commit 8072530

7 files changed

Lines changed: 140 additions & 5 deletions

File tree

20.1 KB
Loading

.github/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ There are 5 ways to install this plugin:
3737

3838
![SearchResults2](Images/SearchResults2Dark.png)
3939

40+
## ADDRESSABLES SUPPORT
41+
42+
This plugin has experimental support for *Addressables* package. However, the search may take significantly longer to finish when Addressables are searched. Some manual modifications are needed to enable Addressables support:
43+
44+
- The plugin mustn't be installed as a package, i.e. it must reside inside the *Assets* folder and not the *Packages* folder (it can reside inside a subfolder of Assets like *Assets/Plugins*)
45+
- Modify the **AssetUsageDetector.Editor** Assembly Definition File as follows:
46+
47+
![AddressablesAssemblyChanges](Images/AddressablesAssemblyChanges.png)
48+
49+
- If *Version Defines* isn't present (on older Unity versions), manually add `ASSET_USAGE_ADDRESSABLES` compiler directive to **Player Settings/Scripting Define Symbols** (these symbols are platform specific, so if you change the active platform later, you'll have to add the compiler directive again)
50+
- Enable the "Addressables support" option in Asset Usage Detector window
51+
4052
## SEARCH REFACTORING
4153

4254
While searching for references using the Scripting API, it's possible to get notified of the found references *during* the search (some references like *Assembly Definition File* references or *Shader Graph* references aren't supported) and in most cases, refactor them (e.g. changing all usages of a searched object with something else or *null*). Disabling *Lazy Scene Search* is recommended while using this feature and it's advised to backup your project beforehand.

Plugins/AssetUsageDetector/Editor/AssetUsageDetector.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ public class Parameters
4747
public SearchRefactoring searchRefactoring = null;
4848

4949
public bool lazySceneSearch = true;
50+
#if ASSET_USAGE_ADDRESSABLES
51+
public bool addressablesSupport = false;
52+
#endif
5053
public bool calculateUnusedObjects = false;
5154
public bool hideDuplicateRows = true;
5255
public bool hideReduntantPrefabVariantLinks = true;
@@ -1103,6 +1106,11 @@ private ReferenceNode SearchObject( object obj )
11031106
// Check if the asset at specified path depends on any of the references
11041107
private bool AssetHasAnyReference( string assetPath )
11051108
{
1109+
#if ASSET_USAGE_ADDRESSABLES
1110+
if( searchParameters.addressablesSupport )
1111+
return true;
1112+
#endif
1113+
11061114
if( assetsToSearchPathsSet.Contains( assetPath ) )
11071115
return true;
11081116

Plugins/AssetUsageDetector/Editor/AssetUsageDetectorSearchFunctions.cs

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#if UNITY_2017_2_OR_NEWER
2222
using UnityEngine.Tilemaps;
2323
#endif
24+
#if ASSET_USAGE_ADDRESSABLES
25+
using UnityEngine.AddressableAssets;
26+
#endif
2427
using Object = UnityEngine.Object;
2528

2629
namespace AssetUsageDetectorNamespace
@@ -198,6 +201,12 @@ private static string ExtractGUIDFromString( string str )
198201
private delegate FieldInfo FieldInfoGetter( SerializedProperty p, out Type t );
199202
private FieldInfoGetter fieldInfoGetter;
200203

204+
#if ASSET_USAGE_ADDRESSABLES
205+
private delegate Sprite[] SpriteAtlasPackedSpritesGetter( SpriteAtlas atlas );
206+
private SpriteAtlasPackedSpritesGetter spriteAtlasPackedSpritesGetter;
207+
private PropertyInfo assetReferenceSubObjectTypeGetter;
208+
#endif
209+
201210
private void InitializeSearchFunctionsData( Parameters searchParameters )
202211
{
203212
if( typeToSearchFunction == null )
@@ -346,6 +355,12 @@ private void InitializeSearchFunctionsData( Parameters searchParameters )
346355
MethodInfo fieldInfoGetterMethod = typeof( Editor ).Assembly.GetType( "UnityEditor.ScriptAttributeUtility" ).GetMethod( "GetFieldInfoFromProperty", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static );
347356
#endif
348357
fieldInfoGetter = (FieldInfoGetter) Delegate.CreateDelegate( typeof( FieldInfoGetter ), fieldInfoGetterMethod );
358+
359+
#if ASSET_USAGE_ADDRESSABLES
360+
MethodInfo spriteAtlasPackedSpritesGetterMethod = typeof( SpriteAtlasExtensions ).GetMethod( "GetPackedSprites", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static );
361+
spriteAtlasPackedSpritesGetter = (SpriteAtlasPackedSpritesGetter) Delegate.CreateDelegate( typeof( SpriteAtlasPackedSpritesGetter ), spriteAtlasPackedSpritesGetterMethod );
362+
assetReferenceSubObjectTypeGetter = typeof( AssetReference ).GetProperty( "SubOjbectType", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance );
363+
#endif
349364
}
350365

351366
private ReferenceNode SearchGameObject( Object unityObject )
@@ -1355,6 +1370,12 @@ private void SearchVariablesWithSerializedObject( ReferenceNode referenceNode )
13551370
{
13561371
if( !isInPlayMode || referenceNode.nodeObject.IsAsset() )
13571372
{
1373+
#if ASSET_USAGE_ADDRESSABLES
1374+
// See: https://github.com/yasirkula/UnityAssetUsageDetector/issues/29
1375+
if( searchParameters.addressablesSupport && ( (Object) referenceNode.nodeObject ).name == "Deprecated EditorExtensionImpl" )
1376+
return;
1377+
#endif
1378+
13581379
SerializedObject so = new SerializedObject( (Object) referenceNode.nodeObject );
13591380
SerializedProperty iterator = so.GetIterator();
13601381
SerializedProperty iteratorVisible = so.GetIterator();
@@ -1404,9 +1425,22 @@ private void SearchVariablesWithSerializedObject( ReferenceNode referenceNode )
14041425
break;
14051426
#endif
14061427
case SerializedPropertyType.Generic:
1407-
propertyValue = null;
1408-
searchResult = null;
1409-
enterChildren = true;
1428+
#if ASSET_USAGE_ADDRESSABLES
1429+
AssetReference assetReference;
1430+
if( searchParameters.addressablesSupport && iterator.type.StartsWithFast( "AssetReference" ) && ( assetReference = GetRawSerializedPropertyValue( iterator ) as AssetReference ) != null )
1431+
{
1432+
propertyValue = GetAddressablesAssetReferenceValue( assetReference );
1433+
searchResult = SearchObject( PreferablyGameObject( propertyValue ) );
1434+
enterChildren = false;
1435+
}
1436+
else
1437+
#endif
1438+
{
1439+
propertyValue = null;
1440+
searchResult = null;
1441+
enterChildren = true;
1442+
}
1443+
14101444
break;
14111445
default:
14121446
propertyValue = null;
@@ -1459,6 +1493,15 @@ private void SearchVariablesWithReflection( ReferenceNode referenceNode )
14591493
// no need to have duplicate search entries
14601494
if( !( variableValue is ICollection ) )
14611495
{
1496+
#if ASSET_USAGE_ADDRESSABLES
1497+
if( searchParameters.addressablesSupport && variableValue is AssetReference )
1498+
{
1499+
variableValue = GetAddressablesAssetReferenceValue( (AssetReference) variableValue );
1500+
if( variableValue == null || variableValue.Equals( null ) )
1501+
continue;
1502+
}
1503+
#endif
1504+
14621505
ReferenceNode searchResult = SearchObject( PreferablyGameObject( variableValue ) );
14631506
if( searchResult != null && searchResult != referenceNode )
14641507
{
@@ -1741,6 +1784,44 @@ private object GetFieldValue( object source, string fieldName, int arrayIndex )
17411784
return enumerator.Current;
17421785
}
17431786

1787+
#if ASSET_USAGE_ADDRESSABLES
1788+
private Object GetAddressablesAssetReferenceValue( AssetReference assetReference )
1789+
{
1790+
Object result = assetReference.editorAsset;
1791+
if( !result )
1792+
return null;
1793+
1794+
string subObjectName = assetReference.SubObjectName;
1795+
if( !string.IsNullOrEmpty( subObjectName ) )
1796+
{
1797+
if( result is SpriteAtlas )
1798+
{
1799+
Sprite[] packedSprites = spriteAtlasPackedSpritesGetter( (SpriteAtlas) result );
1800+
if( packedSprites != null )
1801+
{
1802+
for( int i = 0; i < packedSprites.Length; i++ )
1803+
{
1804+
if( packedSprites[i] && packedSprites[i].name == subObjectName )
1805+
return packedSprites[i];
1806+
}
1807+
}
1808+
}
1809+
else
1810+
{
1811+
Type subObjectType = (Type) assetReferenceSubObjectTypeGetter.GetValue( assetReference, null ) ?? typeof( Object );
1812+
Object[] subAssets = AssetDatabase.LoadAllAssetRepresentationsAtPath( AssetDatabase.GetAssetPath( result ) );
1813+
for( int k = 0; k < subAssets.Length; k++ )
1814+
{
1815+
if( subAssets[k] && subAssets[k].name == subObjectName && subObjectType.IsAssignableFrom( subAssets[k].GetType() ) )
1816+
return subAssets[k];
1817+
}
1818+
}
1819+
}
1820+
1821+
return result;
1822+
}
1823+
#endif
1824+
17441825
// Iterates over all occurrences of specific key-value pairs in string
17451826
// Example1: #include "VALUE" valuePrefix=#include, valueWrapperChar="
17461827
// Example2: "guid": "VALUE" valuePrefix="guid", valueWrapperChar="

Plugins/AssetUsageDetector/Editor/AssetUsageDetectorWindow.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ private enum WindowFilter { AlwaysReturnActive, ReturnActiveIfNotLocked, AlwaysR
3131
private const string PREFS_SEARCH_NON_SERIALIZABLES = "AUD_NonSerializables";
3232
private const string PREFS_SEARCH_UNUSED_MATERIAL_PROPERTIES = "AUD_SearchUnusedMaterialProps";
3333
private const string PREFS_LAZY_SCENE_SEARCH = "AUD_LazySceneSearch";
34+
private const string PREFS_ADDRESSABLES_SUPPORT = "AUD_AddressablesSupport";
3435
private const string PREFS_CALCULATE_UNUSED_OBJECTS = "AUD_FindUnusedObjs";
3536
private const string PREFS_HIDE_DUPLICATE_ROWS = "AUD_HideDuplicates";
3637
private const string PREFS_HIDE_REDUNDANT_PREFAB_VARIANT_LINKS = "AUD_HideRedundantPVariantLinks";
@@ -83,6 +84,9 @@ private bool IsLocked
8384
private int searchDepthLimit = 4; // Depth limit for recursively searching variables of objects
8485

8586
private bool lazySceneSearch = true;
87+
#if ASSET_USAGE_ADDRESSABLES
88+
private bool addressablesSupport = false;
89+
#endif
8690
private bool searchNonSerializableVariables = true;
8791
private bool searchUnusedMaterialProperties = true;
8892
private bool calculateUnusedObjects = false;
@@ -319,6 +323,9 @@ private void ShowAndSearchInternal( IEnumerable<Object> searchObjects, AssetUsag
319323
searchUnusedMaterialProperties = searchParameters.searchUnusedMaterialProperties;
320324
searchRefactoring = searchParameters.searchRefactoring;
321325
lazySceneSearch = searchParameters.lazySceneSearch;
326+
#if ASSET_USAGE_ADDRESSABLES
327+
addressablesSupport = searchParameters.addressablesSupport;
328+
#endif
322329
calculateUnusedObjects = searchParameters.calculateUnusedObjects;
323330
hideDuplicateRows = searchParameters.hideDuplicateRows;
324331
hideReduntantPrefabVariantLinks = searchParameters.hideReduntantPrefabVariantLinks;
@@ -398,6 +405,9 @@ private void SavePrefs()
398405
EditorPrefs.SetBool( PREFS_SEARCH_NON_SERIALIZABLES, searchNonSerializableVariables );
399406
EditorPrefs.SetBool( PREFS_SEARCH_UNUSED_MATERIAL_PROPERTIES, searchUnusedMaterialProperties );
400407
EditorPrefs.SetBool( PREFS_LAZY_SCENE_SEARCH, lazySceneSearch );
408+
#if ASSET_USAGE_ADDRESSABLES
409+
EditorPrefs.SetBool( PREFS_ADDRESSABLES_SUPPORT, addressablesSupport );
410+
#endif
401411
EditorPrefs.SetBool( PREFS_CALCULATE_UNUSED_OBJECTS, calculateUnusedObjects );
402412
EditorPrefs.SetBool( PREFS_HIDE_DUPLICATE_ROWS, hideDuplicateRows );
403413
EditorPrefs.SetBool( PREFS_HIDE_REDUNDANT_PREFAB_VARIANT_LINKS, hideReduntantPrefabVariantLinks );
@@ -417,6 +427,9 @@ private void LoadPrefs()
417427
searchNonSerializableVariables = EditorPrefs.GetBool( PREFS_SEARCH_NON_SERIALIZABLES, true );
418428
searchUnusedMaterialProperties = EditorPrefs.GetBool( PREFS_SEARCH_UNUSED_MATERIAL_PROPERTIES, true );
419429
lazySceneSearch = EditorPrefs.GetBool( PREFS_LAZY_SCENE_SEARCH, true );
430+
#if ASSET_USAGE_ADDRESSABLES
431+
addressablesSupport = EditorPrefs.GetBool( PREFS_ADDRESSABLES_SUPPORT, false );
432+
#endif
420433
calculateUnusedObjects = EditorPrefs.GetBool( PREFS_CALCULATE_UNUSED_OBJECTS, false );
421434
hideDuplicateRows = EditorPrefs.GetBool( PREFS_HIDE_DUPLICATE_ROWS, true );
422435
hideReduntantPrefabVariantLinks = EditorPrefs.GetBool( PREFS_HIDE_REDUNDANT_PREFAB_VARIANT_LINKS, true );
@@ -551,7 +564,14 @@ private void OnGUI()
551564
GUILayout.Box( "<b>SETTINGS</b>", Utilities.BoxGUIStyle, Utilities.GL_EXPAND_WIDTH );
552565
GUI.backgroundColor = c;
553566

567+
#if ASSET_USAGE_ADDRESSABLES
568+
EditorGUI.BeginDisabledGroup( addressablesSupport );
569+
#endif
554570
lazySceneSearch = WordWrappingToggleLeft( "Lazy scene search: scenes are searched in detail only when they are manually refreshed (faster search)", lazySceneSearch );
571+
#if ASSET_USAGE_ADDRESSABLES
572+
EditorGUI.EndDisabledGroup();
573+
addressablesSupport = WordWrappingToggleLeft( "Addressables support (WARNING: 'Lazy scene search' will be disabled) (slower search)", addressablesSupport );
574+
#endif
555575
calculateUnusedObjects = WordWrappingToggleLeft( "Calculate unused objects", calculateUnusedObjects );
556576
hideDuplicateRows = WordWrappingToggleLeft( "Hide duplicate rows in search results", hideDuplicateRows );
557577
#if UNITY_2018_3_OR_NEWER
@@ -687,7 +707,12 @@ private void InitiateSearch()
687707
//searchNonSerializableVariables = searchNonSerializableVariables,
688708
searchUnusedMaterialProperties = searchUnusedMaterialProperties,
689709
searchRefactoring = searchRefactoring,
710+
#if ASSET_USAGE_ADDRESSABLES
711+
lazySceneSearch = lazySceneSearch && !addressablesSupport,
712+
addressablesSupport = addressablesSupport,
713+
#else
690714
lazySceneSearch = lazySceneSearch,
715+
#endif
691716
calculateUnusedObjects = calculateUnusedObjects,
692717
hideDuplicateRows = hideDuplicateRows,
693718
hideReduntantPrefabVariantLinks = hideReduntantPrefabVariantLinks,

Plugins/AssetUsageDetector/README.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
= Asset Usage Detector (v2.2.3) =
1+
= Asset Usage Detector (v2.3.0) =
22

33
Online documentation available at: https://github.com/yasirkula/UnityAssetUsageDetector
44
E-mail: yasirkula@gmail.com
@@ -8,6 +8,15 @@ E-mail: yasirkula@gmail.com
88
This tool helps you find usages of the selected asset(s) and/or scene object(s), i.e. lists the objects that refer to them.
99

1010

11+
### ADDRESSABLES SUPPORT
12+
This plugin has experimental support for Addressables package. However, the search may take significantly longer to finish when Addressables are searched. Some manual modifications are needed to enable Addressables support:
13+
14+
- The plugin mustn't be installed as a package, i.e. it must reside inside the Assets folder and not the Packages folder (it can reside inside a subfolder of Assets like Assets/Plugins)
15+
- Add ASSET_USAGE_ADDRESSABLES compiler directive to "Player Settings/Scripting Define Symbols" (these symbols are platform specific, so if you change the active platform later, you'll have to add the compiler directive again)
16+
- Add "Unity.Addressables" assembly to "AssetUsageDetector.Editor" Assembly Definition File's "Assembly Definition References" list
17+
- Enable the "Addressables support" option in Asset Usage Detector window
18+
19+
1120
### HOW TO
1221
- Open "Window-Asset Usage Detector" window, configure the settings and hit "GO!". You can also right click an object and select "Search For References"
1322

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "com.yasirkula.assetusagedetector",
33
"displayName": "Asset Usage Detector",
4-
"version": "2.2.3",
4+
"version": "2.3.0",
55
"documentationUrl": "https://github.com/yasirkula/UnityAssetUsageDetector",
66
"changelogUrl": "https://github.com/yasirkula/UnityAssetUsageDetector/releases",
77
"licensesUrl": "https://github.com/yasirkula/UnityAssetUsageDetector/blob/master/LICENSE.txt",

0 commit comments

Comments
 (0)