@@ -67,7 +67,6 @@ public static void ParseAssets()
67
67
var objectCount = assetsManager . assetsFileList . Sum ( x => x . Objects . Count ) ;
68
68
var objectAssetItemDic = new Dictionary < AssetStudio . Object , AssetItem > ( objectCount ) ;
69
69
var isL2dMode = CLIOptions . o_workMode . Value == WorkMode . Live2D ;
70
- var l2dSearchByFilename = CLIOptions . f_l2dAssetSearchByFilename . Value ;
71
70
72
71
Progress . Reset ( ) ;
73
72
var i = 0 ;
@@ -175,10 +174,6 @@ public static void ParseAssets()
175
174
if ( m_GameObject . CubismModel != null && TryGetCubismMoc ( m_GameObject . CubismModel . CubismModelMono , out var mocMono ) )
176
175
{
177
176
l2dModelDict [ mocMono ] = m_GameObject . CubismModel ;
178
- if ( ! m_GameObject . CubismModel . IsRoot )
179
- {
180
- FixCubismModelName ( m_GameObject ) ;
181
- }
182
177
}
183
178
break ;
184
179
case Animator m_Animator :
@@ -210,9 +205,7 @@ public static void ParseAssets()
210
205
{
211
206
if ( containers . TryGetValue ( asset . Asset , out var container ) )
212
207
{
213
- asset . Container = isL2dMode && l2dSearchByFilename
214
- ? Path . GetFileName ( asset . Asset . assetsFile . originalPath )
215
- : container ;
208
+ asset . Container = container ;
216
209
217
210
if ( asset . Asset is GameObject m_GameObject && m_GameObject . CubismModel != null )
218
211
{
@@ -778,15 +771,6 @@ private static bool TryGetCubismMoc(MonoBehaviour m_MonoBehaviour, out MonoBehav
778
771
return mocPPtr . TryGet ( out mocMono ) ;
779
772
}
780
773
781
- private static void FixCubismModelName ( GameObject m_GameObject )
782
- {
783
- var rootTransform = GetRootTransform ( m_GameObject . m_Transform ) ;
784
- if ( rootTransform . m_GameObject . TryGet ( out var rootGameObject ) )
785
- {
786
- m_GameObject . CubismModel . Name = rootGameObject . m_Name ;
787
- }
788
- }
789
-
790
774
private static void BindCubismRenderer ( MonoBehaviour m_MonoBehaviour )
791
775
{
792
776
if ( ! m_MonoBehaviour . m_GameObject . TryGet ( out var m_GameObject ) )
@@ -847,58 +831,57 @@ private static Transform GetRootTransform(Transform m_Transform)
847
831
return m_Transform ;
848
832
}
849
833
850
- private static List < string > GenerateMocPathList ( Dictionary < MonoBehaviour , CubismModel > mocDict , bool searchByFilename , ref bool useFullContainerPath )
834
+ private static Dictionary < MonoBehaviour , string > GenerateMocPathDict ( Dictionary < MonoBehaviour , CubismModel > mocDict , Dictionary < AssetStudio . Object , string > assetContainers , bool searchByFilename )
851
835
{
852
- var mocPathDict = new Dictionary < MonoBehaviour , ( string , string ) > ( ) ;
853
- var mocPathList = new List < string > ( ) ;
836
+ var tempMocPathDict = new Dictionary < MonoBehaviour , ( string , string ) > ( ) ;
837
+ var mocPathDict = new Dictionary < MonoBehaviour , string > ( ) ;
854
838
foreach ( var mocMono in l2dModelDict . Keys )
855
839
{
856
- if ( ! containers . TryGetValue ( mocMono , out var containerPath ) )
840
+ if ( ! containers . TryGetValue ( mocMono , out var fullContainerPath ) )
857
841
continue ;
858
- var fullContainerPath = searchByFilename
859
- ? l2dModelDict [ mocMono ] ? . Container ?? containerPath
860
- : containerPath ;
861
842
var pathSepIndex = fullContainerPath . LastIndexOf ( '/' ) ;
862
843
var basePath = pathSepIndex > 0
863
844
? fullContainerPath . Substring ( 0 , pathSepIndex )
864
845
: fullContainerPath ;
865
- mocPathDict . Add ( mocMono , ( fullContainerPath , basePath ) ) ;
846
+ tempMocPathDict . Add ( mocMono , ( fullContainerPath , basePath ) ) ;
866
847
}
867
848
868
- if ( mocPathDict . Count > 0 )
849
+ if ( tempMocPathDict . Count > 0 )
869
850
{
870
- var basePathSet = mocPathDict . Values . Select ( x => x . Item2 ) . ToHashSet ( ) ;
871
- useFullContainerPath = mocPathDict . Count != basePathSet . Count ;
851
+ var basePathSet = tempMocPathDict . Values . Select ( x => x . Item2 ) . ToHashSet ( ) ;
852
+ var useFullContainerPath = tempMocPathDict . Count != basePathSet . Count ;
872
853
foreach ( var moc in mocDict . Keys )
873
854
{
874
855
var mocPath = useFullContainerPath
875
- ? mocPathDict [ moc ] . Item1 //fullContainerPath
876
- : mocPathDict [ moc ] . Item2 ; //basePath
856
+ ? tempMocPathDict [ moc ] . Item1 //fullContainerPath
857
+ : tempMocPathDict [ moc ] . Item2 ; //basePath
877
858
if ( searchByFilename )
878
859
{
879
- mocPathList . Add ( containers [ moc ] ) ;
860
+ mocPathDict . Add ( moc , assetContainers [ moc ] ) ;
880
861
if ( mocDict . TryGetValue ( moc , out var model ) && model != null )
881
862
model . Container = mocPath ;
882
863
}
883
864
else
884
865
{
885
- mocPathList . Add ( mocPath ) ;
866
+ mocPathDict . Add ( moc , mocPath ) ;
886
867
}
887
868
}
888
- mocPathDict . Clear ( ) ;
869
+ tempMocPathDict . Clear ( ) ;
889
870
}
890
- return mocPathList ;
871
+ return mocPathDict ;
891
872
}
892
873
893
874
public static void ExportLive2D ( )
894
875
{
895
876
var baseDestPath = Path . Combine ( CLIOptions . o_outputFolder . Value , "Live2DOutput" ) ;
896
- var useFullContainerPath = true ;
897
877
var motionMode = CLIOptions . o_l2dMotionMode . Value ;
898
878
var forceBezier = CLIOptions . f_l2dForceBezier . Value ;
899
879
var modelGroupOption = CLIOptions . o_l2dGroupOption . Value ;
900
880
var searchByFilename = CLIOptions . f_l2dAssetSearchByFilename . Value ;
901
881
var mocDict = l2dModelDict ; //TODO: filter by name
882
+ var l2dContainers = searchByFilename
883
+ ? new Dictionary < AssetStudio . Object , string > ( )
884
+ : containers ;
902
885
903
886
if ( l2dModelDict . Count == 0 )
904
887
{
@@ -907,41 +890,50 @@ public static void ExportLive2D()
907
890
}
908
891
909
892
Progress . Reset ( ) ;
910
- Logger . Info ( $ "Searching for Live2D files...") ;
893
+ Logger . Info ( "Searching for Live2D files..." ) ;
911
894
912
- var mocPathList = GenerateMocPathList ( mocDict , searchByFilename , ref useFullContainerPath ) ;
895
+ if ( searchByFilename )
896
+ {
897
+ foreach ( var assetKvp in containers )
898
+ {
899
+ l2dContainers [ assetKvp . Key ] = Path . GetFileName ( assetKvp . Key . assetsFile . originalPath ) ;
900
+ }
901
+ }
902
+ var mocPathDict = GenerateMocPathDict ( mocDict , l2dContainers , searchByFilename ) ;
913
903
914
- #if NET9_0_OR_GREATER
915
- var assetDict = new Dictionary < string , List < AssetStudio . Object > > ( ) ;
916
- foreach ( var ( asset , container ) in containers )
904
+ var assetDict = new Dictionary < MonoBehaviour , List < AssetStudio . Object > > ( ) ;
905
+ foreach ( var mocKvp in mocPathDict )
906
+ {
907
+ var mocPath = mocKvp . Value ;
908
+ var result = l2dContainers . Select ( assetKvp =>
917
909
{
918
- var result = mocPathList . Find ( mocPath =>
919
- {
920
- if ( ! container . Contains ( mocPath ) )
921
- return false ;
922
- var mocPathSpan = mocPath . AsSpan ( ) ;
923
- var mocPathLastSlice = mocPathSpan [ ( mocPathSpan . LastIndexOf ( '/' ) + 1 ) ..] ;
924
- foreach ( var range in container . AsSpan ( ) . Split ( '/' ) )
925
- {
926
- if ( mocPathLastSlice . SequenceEqual ( container . AsSpan ( ) [ range ] ) )
927
- return true ;
928
- }
929
- return false ;
930
- } ) ;
931
- if ( result != null )
910
+ if ( ! assetKvp . Value . Contains ( mocPath ) )
911
+ return null ;
912
+ var mocPathSpan = mocPath . AsSpan ( ) ;
913
+ var modelNameFromPath = mocPathSpan . Slice ( mocPathSpan . LastIndexOf ( '/' ) + 1 ) ;
914
+ #if NET9_0_OR_GREATER
915
+ foreach ( var range in assetKvp . Value . AsSpan ( ) . Split ( '/' ) )
932
916
{
933
- if ( assetDict . TryGetValue ( result , out var assets ) )
934
- assets . Add ( asset ) ;
935
- else
936
- assetDict [ result ] = [ asset ] ;
917
+ if ( modelNameFromPath . SequenceEqual ( assetKvp . Value . AsSpan ( ) [ range ] ) )
918
+ return assetKvp . Key ;
937
919
}
938
- }
939
920
#else
940
- var assetDict = containers . AsParallel ( ) . ToLookup (
941
- x => mocPathList . Find ( b => x . Value . Contains ( b ) && x . Value . Split ( '/' ) . Any ( y => y == b . Substring ( b . LastIndexOf ( "/" ) + 1 ) ) ) ,
942
- x => x . Key
943
- ) . Where ( x => x . Key != null ) . ToDictionary ( x => x . Key , x => x . ToList ( ) ) ;
921
+ foreach ( var str in assetKvp . Value . Split ( '/' ) )
922
+ {
923
+ if ( modelNameFromPath . SequenceEqual ( str . AsSpan ( ) ) )
924
+ return assetKvp . Key ;
925
+ }
944
926
#endif
927
+ return null ;
928
+ } ) . Where ( x => x != null ) . ToList ( ) ;
929
+
930
+ if ( result . Count > 0 )
931
+ {
932
+ assetDict [ mocKvp . Key ] = result ;
933
+ }
934
+ }
935
+ if ( searchByFilename )
936
+ l2dContainers . Clear ( ) ;
945
937
if ( mocDict . Keys . First ( ) . serializedType ? . m_Type == null && CLIOptions . o_assemblyPath . Value == "" )
946
938
{
947
939
Logger . Warning ( "Specifying the assembly folder may be needed for proper extraction" ) ;
@@ -953,28 +945,34 @@ public static void ExportLive2D()
953
945
var modelCounter = 0 ;
954
946
Live2DExtractor . MocDict = mocDict ;
955
947
Live2DExtractor . Assembly = assemblyLoader ;
956
- foreach ( var assetKvp in assetDict )
948
+ foreach ( var assetGroupKvp in assetDict )
957
949
{
958
- var srcContainer = assetKvp . Key ;
950
+ var srcContainer = containers [ assetGroupKvp . Key ] ;
959
951
960
952
Logger . Info ( $ "[{ modelCounter + 1 } /{ totalModelCount } ] Exporting Live2D: \" { srcContainer . Color ( Ansi . BrightCyan ) } \" ") ;
961
953
try
962
954
{
963
- var cubismExtractor = new Live2DExtractor ( assetKvp . Value ) ;
955
+ var cubismExtractor = new Live2DExtractor ( assetGroupKvp ) ;
964
956
string modelPath ;
965
- if ( modelGroupOption == Live2DModelGroupOption . SourceFileName )
966
- {
967
- modelPath = Path . GetFileNameWithoutExtension ( cubismExtractor . MocMono . assetsFile . originalPath ) ;
968
- }
969
- else
970
- {
971
- var container = searchByFilename && cubismExtractor . Model != null
972
- ? cubismExtractor . Model . Container
973
- : srcContainer ;
974
- modelPath = Path . HasExtension ( container )
975
- ? container . Replace ( Path . GetExtension ( container ) , "" )
976
- : container ;
977
- }
957
+ switch ( modelGroupOption )
958
+ {
959
+ case Live2DModelGroupOption . SourceFileName :
960
+ modelPath = Path . GetFileNameWithoutExtension ( cubismExtractor . MocMono . assetsFile . originalPath ) ;
961
+ break ;
962
+ case Live2DModelGroupOption . ModelName :
963
+ modelPath = ! string . IsNullOrEmpty ( cubismExtractor . Model ? . Name )
964
+ ? cubismExtractor . Model . Name
965
+ : Path . GetFileNameWithoutExtension ( cubismExtractor . MocMono . assetsFile . originalPath ) ;
966
+ break ;
967
+ default : //ContainerPath
968
+ var container = searchByFilename && cubismExtractor . Model != null
969
+ ? cubismExtractor . Model . Container
970
+ : srcContainer ;
971
+ modelPath = Path . HasExtension ( container )
972
+ ? container . Replace ( Path . GetExtension ( container ) , "" )
973
+ : container ;
974
+ break ;
975
+ }
978
976
979
977
var destPath = Path . Combine ( baseDestPath , modelPath ) + Path . DirectorySeparatorChar ;
980
978
cubismExtractor . ExtractCubismModel ( destPath , motionMode , forceBezier , parallelTaskCount ) ;
0 commit comments