11using System ;
2+ using System . Collections . Generic ;
23using System . IO ;
34
45using Prowl . Echo ;
@@ -94,17 +95,27 @@ private static void ResolveTextures(ModelImportResult data, ImportContext ctx)
9495 string assetsRoot = Project . Current ? . AssetsPath ?? "" ;
9596 if ( string . IsNullOrEmpty ( assetsRoot ) ) return ;
9697
98+ // A disk-backed texture is loaded once by the model importer but can be referenced by
99+ // multiple material slots (the source file references it once, by index), so collect every
100+ // live texture object that gets replaced by an AssetRef here and dispose each only once,
101+ // after every slot referencing it has been resolved - disposing eagerly per-slot would free
102+ // a texture a later slot still needs to read.
103+ var resolved = new HashSet < Texture2D > ( ) ;
104+
97105 foreach ( var mat in data . Materials )
98106 {
99107 if ( mat == null ) continue ;
100- ResolveSlot ( mat , "_MainTex" , modelDir , assetsRoot , db , ctx ) ;
101- ResolveSlot ( mat , "_NormalTex" , modelDir , assetsRoot , db , ctx ) ;
102- ResolveSlot ( mat , "_SurfaceTex" , modelDir , assetsRoot , db , ctx ) ;
103- ResolveSlot ( mat , "_EmissionTex" , modelDir , assetsRoot , db , ctx ) ;
108+ ResolveSlot ( mat , "_MainTex" , modelDir , assetsRoot , db , ctx , resolved ) ;
109+ ResolveSlot ( mat , "_NormalTex" , modelDir , assetsRoot , db , ctx , resolved ) ;
110+ ResolveSlot ( mat , "_SurfaceTex" , modelDir , assetsRoot , db , ctx , resolved ) ;
111+ ResolveSlot ( mat , "_EmissionTex" , modelDir , assetsRoot , db , ctx , resolved ) ;
104112 }
113+
114+ foreach ( var tex in resolved )
115+ tex . Dispose ( ) ;
105116 }
106117
107- private static void ResolveSlot ( Material mat , string slot , string modelDir , string assetsRoot , EditorAssetDatabase db , ImportContext ctx )
118+ private static void ResolveSlot ( Material mat , string slot , string modelDir , string assetsRoot , EditorAssetDatabase db , ImportContext ctx , HashSet < Texture2D > resolved )
108119 {
109120 var tex = mat . _properties . GetTexture ( slot ) ;
110121 if ( tex == null || tex . IsDisposed ) return ;
@@ -113,16 +124,27 @@ private static void ResolveSlot(Material mat, string slot, string modelDir, stri
113124 if ( string . IsNullOrEmpty ( texPath ) ) return ;
114125
115126 string ? relativePath = null ;
116- if ( Path . IsPathRooted ( texPath ) )
127+ try
117128 {
118- if ( texPath . StartsWith ( assetsRoot , StringComparison . OrdinalIgnoreCase ) )
119- relativePath = Path . GetRelativePath ( assetsRoot , texPath ) . Replace ( '\\ ' , '/' ) ;
129+ if ( Path . IsPathRooted ( texPath ) )
130+ {
131+ if ( texPath . StartsWith ( assetsRoot , StringComparison . OrdinalIgnoreCase ) )
132+ relativePath = Path . GetRelativePath ( assetsRoot , texPath ) . Replace ( '\\ ' , '/' ) ;
133+ }
134+ else
135+ {
136+ string abs = Path . GetFullPath ( Path . Combine ( modelDir , texPath ) ) ;
137+ if ( abs . StartsWith ( assetsRoot , StringComparison . OrdinalIgnoreCase ) )
138+ relativePath = Path . GetRelativePath ( assetsRoot , abs ) . Replace ( '\\ ' , '/' ) ;
139+ }
120140 }
121- else
141+ catch ( Exception )
122142 {
123- string abs = Path . GetFullPath ( Path . Combine ( modelDir , texPath ) ) ;
124- if ( abs . StartsWith ( assetsRoot , StringComparison . OrdinalIgnoreCase ) )
125- relativePath = Path . GetRelativePath ( assetsRoot , abs ) . Replace ( '\\ ' , '/' ) ;
143+ // tex.AssetPath isn't a real filesystem path - e.g. a shared built-in/default texture
144+ // (Texture2D.LoadDefault fallback for an unset material slot) carries a synthetic
145+ // "$Default:Texture/Normal"-style identifier, and the embedded ':' makes Path.GetFullPath
146+ // throw NotSupportedException on Windows. Nothing to resolve; leave the live texture as-is.
147+ return ;
126148 }
127149
128150 if ( relativePath == null ) return ;
@@ -135,6 +157,7 @@ private static void ResolveSlot(Material mat, string slot, string modelDir, stri
135157 // At runtime, AssetRef lazy-loads via AssetDatabase.Get().
136158 mat . SetTexture ( slot , new AssetRef < Texture2D > ( entry . Guid ) ) ;
137159 ctx . AddDependency ( entry . Guid ) ;
160+ resolved . Add ( tex ) ;
138161 }
139162
140163 public override EchoObject ? DefaultSettings ( )
0 commit comments