1+ namespace GenericUnityObjects . Editor . Util
2+ {
3+ using System ;
4+ using System . IO ;
5+ using NUnit . Framework ;
6+ using UnityEditor ;
7+ using UnityEngine ;
8+
9+ internal static class IconFinder
10+ {
11+ public static bool TryGetCustomIcon ( string genericTypeGUID , out Texture2D customIcon , bool isScriptableObject )
12+ {
13+ customIcon = null ;
14+
15+ string assetPath = AssetDatabase . GUIDToAssetPath ( genericTypeGUID ) ;
16+
17+ if ( string . IsNullOrEmpty ( assetPath ) )
18+ return false ;
19+
20+ if ( TryGetCustomIcon ( assetPath , out customIcon ) )
21+ return true ;
22+
23+ // If generated type inherits from MonoBehaviour, a default script icon must be set, but for scriptable
24+ // objects, it is not the case.
25+ return ! isScriptableObject && TryGetDefaultIconFromMonoBehaviourScript ( assetPath , out customIcon ) ;
26+ }
27+
28+ private static bool TryGetDefaultIconFromMonoBehaviourScript ( string assetPath , out Texture2D customIcon )
29+ {
30+ var monoScript = AssetDatabase . LoadAssetAtPath < MonoScript > ( assetPath ) ;
31+
32+ if ( monoScript is null )
33+ {
34+ customIcon = null ;
35+ return false ;
36+ }
37+
38+ customIcon = AssetPreview . GetMiniThumbnail ( monoScript ) ;
39+ return true ;
40+ }
41+
42+ private static bool TryGetCustomIcon ( string assetPath , out Texture2D customIcon )
43+ {
44+ // Unity doesn't expose any method to get icon guid or Texture2D from MonoScript, so we have to parse the .meta file manually.
45+ // AssetPreview.GetMiniThumbnail returns the icon, but in 2021 it has the DontSave flag and can't be used to set as a custom icon for an asset.
46+
47+ string iconLine = GetIconLine ( assetPath ) ;
48+
49+ if ( iconLine == null )
50+ {
51+ customIcon = null ;
52+ return false ;
53+ }
54+
55+ string guid = GetGUIDFromIconLine ( iconLine ) ;
56+ string texturePath = AssetDatabase . GUIDToAssetPath ( guid ) ;
57+ customIcon = AssetDatabase . LoadAssetAtPath < Texture2D > ( texturePath ) ;
58+ Assert . IsNotNull ( customIcon ) ;
59+ return true ;
60+ }
61+
62+ private static string GetGUIDFromIconLine ( string iconLine )
63+ {
64+ int guidIndex = iconLine . IndexOf ( "guid: " , StringComparison . Ordinal ) ;
65+ return iconLine . Substring ( guidIndex + 6 , 32 ) ;
66+ }
67+
68+ private static string GetIconLine ( string assetPath )
69+ {
70+ string [ ] metaContentLines = File . ReadAllLines ( $ "{ assetPath } .meta") ;
71+
72+ foreach ( string line in metaContentLines )
73+ {
74+ if ( line . StartsWith ( " icon: " ) )
75+ return line ;
76+ }
77+
78+ return null ;
79+ }
80+ }
81+ }
0 commit comments