Add assembly folder support for Live2D export

This commit is contained in:
VaDiM 2023-07-02 23:36:22 +03:00
parent aea6cbc97f
commit 63564d5fff
5 changed files with 49 additions and 39 deletions

View File

@ -9,8 +9,6 @@ namespace AssetStudioCLI
{ {
internal static class Exporter internal static class Exporter
{ {
public static AssemblyLoader assemblyLoader = new AssemblyLoader();
public static bool ExportTexture2D(AssetItem item, string exportPath, CLIOptions options) public static bool ExportTexture2D(AssetItem item, string exportPath, CLIOptions options)
{ {
var m_Texture2D = (Texture2D)item.Asset; var m_Texture2D = (Texture2D)item.Asset;
@ -162,7 +160,7 @@ namespace AssetStudioCLI
return true; return true;
} }
public static bool ExportMonoBehaviour(AssetItem item, string exportPath, CLIOptions options) public static bool ExportMonoBehaviour(AssetItem item, string exportPath, AssemblyLoader assemblyLoader)
{ {
if (!TryExportFile(exportPath, item, ".json", out var exportFullPath)) if (!TryExportFile(exportPath, item, ".json", out var exportFullPath))
return false; return false;
@ -170,14 +168,18 @@ namespace AssetStudioCLI
var type = m_MonoBehaviour.ToType(); var type = m_MonoBehaviour.ToType();
if (type == null) if (type == null)
{ {
var m_Type = MonoBehaviourToTypeTree(m_MonoBehaviour, options); var m_Type = m_MonoBehaviour.ConvertToTypeTree(assemblyLoader);
type = m_MonoBehaviour.ToType(m_Type); type = m_MonoBehaviour.ToType(m_Type);
} }
var str = JsonConvert.SerializeObject(type, Formatting.Indented); if (type != null)
File.WriteAllText(exportFullPath, str); {
var str = JsonConvert.SerializeObject(type, Formatting.Indented);
File.WriteAllText(exportFullPath, str);
Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\"");
return true; return true;
}
return false;
} }
public static bool ExportFont(AssetItem item, string exportPath) public static bool ExportFont(AssetItem item, string exportPath)
@ -232,14 +234,14 @@ namespace AssetStudioCLI
return true; return true;
} }
public static bool ExportDumpFile(AssetItem item, string exportPath, CLIOptions options) public static bool ExportDumpFile(AssetItem item, string exportPath, AssemblyLoader assemblyLoader)
{ {
if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath)) if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath))
return false; return false;
var str = item.Asset.Dump(); var str = item.Asset.Dump();
if (str == null && item.Asset is MonoBehaviour m_MonoBehaviour) if (str == null && item.Asset is MonoBehaviour m_MonoBehaviour)
{ {
var m_Type = MonoBehaviourToTypeTree(m_MonoBehaviour, options); var m_Type = m_MonoBehaviour.ConvertToTypeTree(assemblyLoader);
str = m_MonoBehaviour.Dump(m_Type); str = m_MonoBehaviour.Dump(m_Type);
} }
if (str != null) if (str != null)
@ -367,7 +369,7 @@ namespace AssetStudioCLI
return true; return true;
} }
public static bool ExportConvertFile(AssetItem item, string exportPath, CLIOptions options) public static bool ExportConvertFile(AssetItem item, string exportPath, CLIOptions options, AssemblyLoader assemblyLoader)
{ {
switch (item.Type) switch (item.Type)
{ {
@ -384,7 +386,7 @@ namespace AssetStudioCLI
case ClassIDType.TextAsset: case ClassIDType.TextAsset:
return ExportTextAsset(item, exportPath, options); return ExportTextAsset(item, exportPath, options);
case ClassIDType.MonoBehaviour: case ClassIDType.MonoBehaviour:
return ExportMonoBehaviour(item, exportPath, options); return ExportMonoBehaviour(item, exportPath, assemblyLoader);
case ClassIDType.Font: case ClassIDType.Font:
return ExportFont(item, exportPath); return ExportFont(item, exportPath);
case ClassIDType.Sprite: case ClassIDType.Sprite:
@ -396,23 +398,6 @@ namespace AssetStudioCLI
} }
} }
public static TypeTree MonoBehaviourToTypeTree(MonoBehaviour m_MonoBehaviour, CLIOptions options)
{
if (!assemblyLoader.Loaded)
{
var assemblyFolder = options.o_assemblyPath.Value;
if (assemblyFolder != "")
{
assemblyLoader.Load(assemblyFolder);
}
else
{
assemblyLoader.Loaded = true;
}
}
return m_MonoBehaviour.ConvertToTypeTree(assemblyLoader);
}
public static string FixFileName(string str) public static string FixFileName(string str)
{ {
if (str.Length >= 260) return Path.GetRandomFileName(); if (str.Length >= 260) return Path.GetRandomFileName();

View File

@ -806,6 +806,7 @@ namespace AssetStudioCLI.Options
sb.AppendLine($"# Log Level: {o_logLevel}"); sb.AppendLine($"# Log Level: {o_logLevel}");
sb.AppendLine($"# Log Output: {o_logOutput}"); sb.AppendLine($"# Log Output: {o_logOutput}");
sb.AppendLine($"# Export Asset List: {o_exportAssetList}"); sb.AppendLine($"# Export Asset List: {o_exportAssetList}");
sb.AppendLine($"# Assebmly Path: \"{o_assemblyPath}\"");
sb.AppendLine($"# Unity Version: \"{o_unityVersion}\""); sb.AppendLine($"# Unity Version: \"{o_unityVersion}\"");
break; break;
default: default:

View File

@ -16,12 +16,21 @@ namespace AssetStudioCLI
public AssetsManager assetsManager = new AssetsManager(); public AssetsManager assetsManager = new AssetsManager();
public List<AssetItem> parsedAssetsList = new List<AssetItem>(); public List<AssetItem> parsedAssetsList = new List<AssetItem>();
private static Dictionary<AssetStudio.Object, string> containers = new Dictionary<AssetStudio.Object, string>(); private static Dictionary<AssetStudio.Object, string> containers = new Dictionary<AssetStudio.Object, string>();
private static AssemblyLoader assemblyLoader = new AssemblyLoader();
private readonly CLIOptions options; private readonly CLIOptions options;
public Studio(CLIOptions cliOptions) public Studio(CLIOptions cliOptions)
{ {
Progress.Default = new Progress<int>(ShowCurProgressValue); Progress.Default = new Progress<int>(ShowCurProgressValue);
options = cliOptions; options = cliOptions;
if (options.o_assemblyPath.Value != "")
{
assemblyLoader.Load(options.o_assemblyPath.Value);
}
else
{
assemblyLoader.Loaded = true;
}
} }
private void ShowCurProgressValue(int value) private void ShowCurProgressValue(int value)
@ -308,14 +317,14 @@ namespace AssetStudioCLI
break; break;
case WorkMode.Dump: case WorkMode.Dump:
Logger.Debug($"{options.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}"); Logger.Debug($"{options.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}");
if (ExportDumpFile(asset, exportPath, options)) if (ExportDumpFile(asset, exportPath, assemblyLoader))
{ {
exportedCount++; exportedCount++;
} }
break; break;
case WorkMode.Export: case WorkMode.Export:
Logger.Debug($"{options.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}"); Logger.Debug($"{options.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}");
if (ExportConvertFile(asset, exportPath, options)) if (ExportConvertFile(asset, exportPath, options, assemblyLoader))
{ {
exportedCount++; exportedCount++;
} }
@ -438,7 +447,7 @@ namespace AssetStudioCLI
container = Path.HasExtension(container) ? container.Replace(Path.GetExtension(container), "") : container; container = Path.HasExtension(container) ? container.Replace(Path.GetExtension(container), "") : container;
var destPath = Path.Combine(baseDestPath, container) + Path.DirectorySeparatorChar; var destPath = Path.Combine(baseDestPath, container) + Path.DirectorySeparatorChar;
ExtractLive2D(assets, destPath, modelName); ExtractLive2D(assets, destPath, modelName, assemblyLoader);
modelCounter++; modelCounter++;
} }
catch (Exception ex) catch (Exception ex)

View File

@ -786,7 +786,7 @@ namespace AssetStudioGUI
container = Path.HasExtension(container) ? container.Replace(Path.GetExtension(container), "") : container; container = Path.HasExtension(container) ? container.Replace(Path.GetExtension(container), "") : container;
var destPath = Path.Combine(baseDestPath, container) + Path.DirectorySeparatorChar; var destPath = Path.Combine(baseDestPath, container) + Path.DirectorySeparatorChar;
ExtractLive2D(assets, destPath, modelName); ExtractLive2D(assets, destPath, modelName, assemblyLoader);
modelCounter++; modelCounter++;
} }
catch (Exception ex) catch (Exception ex)

View File

@ -18,7 +18,7 @@ namespace CubismLive2DExtractor
{ {
public static class Live2DExtractor public static class Live2DExtractor
{ {
public static void ExtractLive2D(IGrouping<string, AssetStudio.Object> assets, string destPath, string modelName) public static void ExtractLive2D(IGrouping<string, AssetStudio.Object> assets, string destPath, string modelName, AssemblyLoader assemblyLoader)
{ {
var destTexturePath = Path.Combine(destPath, "textures") + Path.DirectorySeparatorChar; var destTexturePath = Path.Combine(destPath, "textures") + Path.DirectorySeparatorChar;
var destMotionPath = Path.Combine(destPath, "motions") + Path.DirectorySeparatorChar; var destMotionPath = Path.Combine(destPath, "motions") + Path.DirectorySeparatorChar;
@ -63,7 +63,7 @@ namespace CubismLive2DExtractor
{ {
try try
{ {
var buff = ParsePhysics(physics); var buff = ParsePhysics(physics, assemblyLoader);
File.WriteAllText($"{destPath}{modelName}.physics3.json", buff); File.WriteAllText($"{destPath}{modelName}.physics3.json", buff);
} }
catch (Exception e) catch (Exception e)
@ -227,7 +227,15 @@ namespace CubismLive2DExtractor
var expressionName = fullName.Replace(".exp3", ""); var expressionName = fullName.Replace(".exp3", "");
var expressionObj = monoBehaviour.ToType(); var expressionObj = monoBehaviour.ToType();
if (expressionObj == null) if (expressionObj == null)
continue; {
var m_Type = monoBehaviour.ConvertToTypeTree(assemblyLoader);
expressionObj = monoBehaviour.ToType(m_Type);
if (expressionObj == null)
{
Logger.Warning($"Expression \"{expressionName}\" is not readable.");
continue;
}
}
var expression = JsonConvert.DeserializeObject<CubismExpression3Json>(JsonConvert.SerializeObject(expressionObj)); var expression = JsonConvert.DeserializeObject<CubismExpression3Json>(JsonConvert.SerializeObject(expressionObj));
expressions.Add(new JObject expressions.Add(new JObject
@ -311,11 +319,18 @@ namespace CubismLive2DExtractor
File.WriteAllText($"{destPath}{modelName}.model3.json", JsonConvert.SerializeObject(model3, Formatting.Indented)); File.WriteAllText($"{destPath}{modelName}.model3.json", JsonConvert.SerializeObject(model3, Formatting.Indented));
} }
private static string ParsePhysics(MonoBehaviour physics) private static string ParsePhysics(MonoBehaviour physics, AssemblyLoader assemblyLoader)
{ {
var physicsObj = physics.ToType(); var physicsObj = physics.ToType();
if (physicsObj == null) if (physicsObj == null)
throw new Exception("MonoBehaviour is not readable."); {
var m_Type = physics.ConvertToTypeTree(assemblyLoader);
physicsObj = physics.ToType(m_Type);
if (physicsObj == null)
{
throw new Exception("MonoBehaviour is not readable.");
}
}
var cubismPhysicsRig = JsonConvert.DeserializeObject<CubismPhysics>(JsonConvert.SerializeObject(physicsObj))._rig; var cubismPhysicsRig = JsonConvert.DeserializeObject<CubismPhysics>(JsonConvert.SerializeObject(physicsObj))._rig;
var physicsSettings = new CubismPhysics3Json.SerializablePhysicsSettings[cubismPhysicsRig.SubRigs.Length]; var physicsSettings = new CubismPhysics3Json.SerializablePhysicsSettings[cubismPhysicsRig.SubRigs.Length];