mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-06-03 00:58:13 -04:00
[AK][CLI] Add support for portrait sprites
This commit is contained in:
parent
572e3bf0d6
commit
381a7d89ae
@ -37,7 +37,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
filteredAssetTypesList.Add(ClassIDType.MonoScript);
|
filteredAssetTypesList.Add(ClassIDType.MonoScript);
|
||||||
}
|
}
|
||||||
if (classIDTypes.Contains(ClassIDType.Sprite))
|
if (classIDTypes.Contains(ClassIDType.Sprite) || classIDTypes.Contains(ClassIDType.AkPortraitSprite))
|
||||||
{
|
{
|
||||||
filteredAssetTypesList.UnionWith(new HashSet<ClassIDType>
|
filteredAssetTypesList.UnionWith(new HashSet<ClassIDType>
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
using AssetStudio;
|
using Arknights.PortraitSpriteMono;
|
||||||
|
using AssetStudio;
|
||||||
using AssetStudioCLI;
|
using AssetStudioCLI;
|
||||||
using AssetStudioCLI.Options;
|
using AssetStudioCLI.Options;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using SixLabors.ImageSharp.Processing;
|
using SixLabors.ImageSharp.Processing;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Arknights
|
namespace Arknights
|
||||||
@ -83,6 +86,61 @@ namespace Arknights
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Image<Bgra32> AkGetImage(this PortraitSprite portraitSprite, SpriteMaskMode spriteMaskMode = SpriteMaskMode.On)
|
||||||
|
{
|
||||||
|
if (portraitSprite.Texture != null && portraitSprite.AlphaTexture != null)
|
||||||
|
{
|
||||||
|
var tex = CutImage(portraitSprite.Texture.ConvertToImage(false), portraitSprite.TextureRect, portraitSprite.DownscaleMultiplier, portraitSprite.Rotate);
|
||||||
|
|
||||||
|
if (spriteMaskMode == SpriteMaskMode.Off)
|
||||||
|
{
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var alphaTex = CutImage(portraitSprite.AlphaTexture.ConvertToImage(false), portraitSprite.TextureRect, portraitSprite.DownscaleMultiplier, portraitSprite.Rotate);
|
||||||
|
tex.ApplyRGBMask(alphaTex);
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<PortraitSprite> GeneratePortraits(AssetItem asset)
|
||||||
|
{
|
||||||
|
var portraits = new List<PortraitSprite>();
|
||||||
|
|
||||||
|
var portraitsDict = ((MonoBehaviour)asset.Asset).ToType();
|
||||||
|
if (portraitsDict == null)
|
||||||
|
{
|
||||||
|
Logger.Warning("Portraits MonoBehaviour is not readable.");
|
||||||
|
return portraits;
|
||||||
|
}
|
||||||
|
var portraitsJson = JsonConvert.SerializeObject(portraitsDict);
|
||||||
|
var portraitsData = JsonConvert.DeserializeObject<PortraitSpriteConfig>(portraitsJson);
|
||||||
|
|
||||||
|
var atlasTex = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == portraitsData._atlas.Texture.m_PathID).Asset;
|
||||||
|
var atlasAlpha = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == portraitsData._atlas.Alpha.m_PathID).Asset;
|
||||||
|
|
||||||
|
foreach (var portraitData in portraitsData._sprites)
|
||||||
|
{
|
||||||
|
var portraitSprite = new PortraitSprite()
|
||||||
|
{
|
||||||
|
Name = portraitData.Name,
|
||||||
|
AssetsFile = atlasTex.assetsFile,
|
||||||
|
Container = asset.Container,
|
||||||
|
Texture = atlasTex,
|
||||||
|
AlphaTexture = atlasAlpha,
|
||||||
|
TextureRect = new Rectf(portraitData.Rect.X, portraitData.Rect.Y, portraitData.Rect.W, portraitData.Rect.H),
|
||||||
|
Rotate = portraitData.Rotate,
|
||||||
|
};
|
||||||
|
portraits.Add(portraitSprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
return portraits;
|
||||||
|
}
|
||||||
|
|
||||||
private static void ApplyRGBMask(this Image<Bgra32> tex, Image<Bgra32> texMask)
|
private static void ApplyRGBMask(this Image<Bgra32> tex, Image<Bgra32> texMask)
|
||||||
{
|
{
|
||||||
using (texMask)
|
using (texMask)
|
||||||
@ -120,29 +178,31 @@ namespace Arknights
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Image<Bgra32> CutImage(Image<Bgra32> originalImage, Rectf textureRect, float downscaleMultiplier)
|
private static Image<Bgra32> CutImage(Image<Bgra32> originalImage, Rectf textureRect, float downscaleMultiplier, bool rotate = false)
|
||||||
{
|
{
|
||||||
if (originalImage != null)
|
if (originalImage != null)
|
||||||
{
|
{
|
||||||
using (originalImage)
|
if (downscaleMultiplier > 0f && downscaleMultiplier != 1f)
|
||||||
{
|
{
|
||||||
if (downscaleMultiplier > 0f && downscaleMultiplier != 1f)
|
var newSize = (Size)(originalImage.Size() / downscaleMultiplier);
|
||||||
{
|
originalImage.Mutate(x => x.Resize(newSize, KnownResamplers.Lanczos3, compand: true));
|
||||||
var newSize = (Size)(originalImage.Size() / downscaleMultiplier);
|
|
||||||
originalImage.Mutate(x => x.Resize(newSize, KnownResamplers.Lanczos3, compand: true));
|
|
||||||
}
|
|
||||||
var rectX = (int)Math.Floor(textureRect.x);
|
|
||||||
var rectY = (int)Math.Floor(textureRect.y);
|
|
||||||
var rectRight = (int)Math.Ceiling(textureRect.x + textureRect.width);
|
|
||||||
var rectBottom = (int)Math.Ceiling(textureRect.y + textureRect.height);
|
|
||||||
rectRight = Math.Min(rectRight, originalImage.Width);
|
|
||||||
rectBottom = Math.Min(rectBottom, originalImage.Height);
|
|
||||||
var rect = new Rectangle(rectX, rectY, rectRight - rectX, rectBottom - rectY);
|
|
||||||
var spriteImage = originalImage.Clone(x => x.Crop(rect));
|
|
||||||
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
|
|
||||||
|
|
||||||
return spriteImage;
|
|
||||||
}
|
}
|
||||||
|
var rectX = (int)Math.Floor(textureRect.x);
|
||||||
|
var rectY = (int)Math.Floor(textureRect.y);
|
||||||
|
var rectRight = (int)Math.Ceiling(textureRect.x + textureRect.width);
|
||||||
|
var rectBottom = (int)Math.Ceiling(textureRect.y + textureRect.height);
|
||||||
|
rectRight = Math.Min(rectRight, originalImage.Width);
|
||||||
|
rectBottom = Math.Min(rectBottom, originalImage.Height);
|
||||||
|
var rect = new Rectangle(rectX, rectY, rectRight - rectX, rectBottom - rectY);
|
||||||
|
var spriteImage = originalImage.Clone(x => x.Crop(rect));
|
||||||
|
originalImage.Dispose();
|
||||||
|
if (rotate)
|
||||||
|
{
|
||||||
|
spriteImage.Mutate(x => x.Rotate(RotateMode.Rotate270));
|
||||||
|
}
|
||||||
|
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
|
||||||
|
|
||||||
|
return spriteImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Arknights.AvgCharHub;
|
using Arknights.AvgCharHubMono;
|
||||||
using AssetStudio;
|
using AssetStudio;
|
||||||
using AssetStudioCLI;
|
using AssetStudioCLI;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using AssetStudio;
|
using AssetStudio;
|
||||||
|
|
||||||
namespace Arknights.AvgCharHub
|
namespace Arknights.AvgCharHubMono
|
||||||
{
|
{
|
||||||
internal class AvgAssetIDs
|
internal class AvgAssetIDs
|
||||||
{
|
{
|
||||||
|
24
AssetStudioCLI/Components/Arknights/PortraitSprite.cs
Normal file
24
AssetStudioCLI/Components/Arknights/PortraitSprite.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using AssetStudio;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Arknights
|
||||||
|
{
|
||||||
|
internal class PortraitSprite
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public ClassIDType Type { get; }
|
||||||
|
public SerializedFile AssetsFile { get; set; }
|
||||||
|
public string Container { get; set; }
|
||||||
|
public Texture2D Texture { get; set; }
|
||||||
|
public Texture2D AlphaTexture { get; set; }
|
||||||
|
public Rectf TextureRect { get; set; }
|
||||||
|
public bool Rotate { get; set; }
|
||||||
|
public float DownscaleMultiplier { get; }
|
||||||
|
|
||||||
|
public PortraitSprite()
|
||||||
|
{
|
||||||
|
Type = ClassIDType.AkPortraitSprite;
|
||||||
|
DownscaleMultiplier = 1f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
41
AssetStudioCLI/Components/Arknights/PortraitSpriteConfig.cs
Normal file
41
AssetStudioCLI/Components/Arknights/PortraitSpriteConfig.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
namespace Arknights.PortraitSpriteMono
|
||||||
|
{
|
||||||
|
internal class PortraitRect
|
||||||
|
{
|
||||||
|
public float X { get; set; }
|
||||||
|
public float Y { get; set; }
|
||||||
|
public float W { get; set; }
|
||||||
|
public float H { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AtlasSprite
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Guid { get; set; }
|
||||||
|
public int Atlas { get; set; }
|
||||||
|
public PortraitRect Rect { get; set; }
|
||||||
|
public bool Rotate { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class TextureIDs
|
||||||
|
{
|
||||||
|
public int m_FileID { get; set; }
|
||||||
|
public long m_PathID { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AtlasInfo
|
||||||
|
{
|
||||||
|
public int Index { get; set; }
|
||||||
|
public TextureIDs Texture { get; set; }
|
||||||
|
public TextureIDs Alpha { get; set; }
|
||||||
|
public int Size { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class PortraitSpriteConfig
|
||||||
|
{
|
||||||
|
public string m_Name { get; set; }
|
||||||
|
public AtlasSprite[] _sprites { get; set; }
|
||||||
|
public AtlasInfo _atlas { get; set; }
|
||||||
|
public int _index { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using AssetStudio;
|
using Arknights;
|
||||||
|
using AssetStudio;
|
||||||
|
|
||||||
namespace AssetStudioCLI
|
namespace AssetStudioCLI
|
||||||
{
|
{
|
||||||
@ -13,6 +14,7 @@ namespace AssetStudioCLI
|
|||||||
public ClassIDType Type;
|
public ClassIDType Type;
|
||||||
public string Text;
|
public string Text;
|
||||||
public string UniqueID;
|
public string UniqueID;
|
||||||
|
public PortraitSprite AkPortraitSprite;
|
||||||
|
|
||||||
public AssetItem(Object asset)
|
public AssetItem(Object asset)
|
||||||
{
|
{
|
||||||
@ -23,5 +25,17 @@ namespace AssetStudioCLI
|
|||||||
m_PathID = asset.m_PathID;
|
m_PathID = asset.m_PathID;
|
||||||
FullSize = asset.byteSize;
|
FullSize = asset.byteSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AssetItem(PortraitSprite akPortraitSprite)
|
||||||
|
{
|
||||||
|
Asset = null;
|
||||||
|
SourceFile = akPortraitSprite.AssetsFile;
|
||||||
|
Container = akPortraitSprite.Container;
|
||||||
|
Type = akPortraitSprite.Type;
|
||||||
|
TypeString = Type.ToString();
|
||||||
|
Text = akPortraitSprite.Name;
|
||||||
|
m_PathID = -1;
|
||||||
|
AkPortraitSprite = akPortraitSprite;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using SixLabors.ImageSharp;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace AssetStudioCLI
|
namespace AssetStudioCLI
|
||||||
{
|
{
|
||||||
@ -224,15 +225,16 @@ namespace AssetStudioCLI
|
|||||||
{
|
{
|
||||||
alias = $"_{avgSprite.Alias}";
|
alias = $"_{avgSprite.Alias}";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!CLIOptions.f_akOriginalAvgNames.Value)
|
if (!CLIOptions.f_akOriginalAvgNames.Value)
|
||||||
{
|
|
||||||
if ((m_Sprite.m_Name.Length < 3 && m_Sprite.m_Name.All(char.IsDigit)) //not grouped ("spriteIndex")
|
|
||||||
|| (m_Sprite.m_Name.Length < 5 && m_Sprite.m_Name.Contains('$') && m_Sprite.m_Name.Split('$')[0].All(char.IsDigit))) //grouped ("spriteIndex$groupIndex")
|
|
||||||
{
|
{
|
||||||
var fullName = Path.GetFileNameWithoutExtension(item.Container);
|
var groupedPattern = new Regex(@"^\d{1,2}\$\d{1,2}$"); // "spriteIndex$groupIndex"
|
||||||
item.Text = $"{fullName}#{m_Sprite.m_Name}";
|
var notGroupedPattern = new Regex(@"^\d{1,2}$"); // "spriteIndex"
|
||||||
|
if (groupedPattern.IsMatch(m_Sprite.m_Name) || notGroupedPattern.IsMatch(m_Sprite.m_Name))
|
||||||
|
{
|
||||||
|
var fullName = Path.GetFileNameWithoutExtension(item.Container);
|
||||||
|
item.Text = $"{fullName}#{m_Sprite.m_Name}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,8 +274,36 @@ namespace AssetStudioCLI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool ExportPortraitSprite(AssetItem item, string exportPath)
|
||||||
|
{
|
||||||
|
var type = CLIOptions.o_imageFormat.Value;
|
||||||
|
var spriteMaskMode = CLIOptions.o_akSpriteMaskMode.Value != AkSpriteMaskMode.None ? SpriteMaskMode.Export : SpriteMaskMode.Off;
|
||||||
|
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var image = item.AkPortraitSprite.AkGetImage(spriteMaskMode: spriteMaskMode);
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
using (image)
|
||||||
|
{
|
||||||
|
using (var file = File.OpenWrite(exportFullPath))
|
||||||
|
{
|
||||||
|
image.WriteToStream(file, type);
|
||||||
|
}
|
||||||
|
Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool ExportRawFile(AssetItem item, string exportPath)
|
public static bool ExportRawFile(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
|
if (item.Asset == null)
|
||||||
|
{
|
||||||
|
Logger.Warning($"Raw export is not supported for \"{item.Text}\" ({item.TypeString}) file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!TryExportFile(exportPath, item, ".dat", out var exportFullPath))
|
if (!TryExportFile(exportPath, item, ".dat", out var exportFullPath))
|
||||||
return false;
|
return false;
|
||||||
File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());
|
File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());
|
||||||
@ -284,6 +314,11 @@ namespace AssetStudioCLI
|
|||||||
|
|
||||||
public static bool ExportDumpFile(AssetItem item, string exportPath)
|
public static bool ExportDumpFile(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
|
if (item.Asset == null)
|
||||||
|
{
|
||||||
|
Logger.Warning($"Dump is not supported for \"{item.Text}\" ({item.TypeString}) file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
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();
|
||||||
@ -439,6 +474,8 @@ namespace AssetStudioCLI
|
|||||||
return ExportFont(item, exportPath);
|
return ExportFont(item, exportPath);
|
||||||
case ClassIDType.Sprite:
|
case ClassIDType.Sprite:
|
||||||
return ExportSprite(item, exportPath);
|
return ExportSprite(item, exportPath);
|
||||||
|
case ClassIDType.AkPortraitSprite:
|
||||||
|
return ExportPortraitSprite(item, exportPath);
|
||||||
case ClassIDType.Mesh:
|
case ClassIDType.Mesh:
|
||||||
return ExportMesh(item, exportPath);
|
return ExportMesh(item, exportPath);
|
||||||
default:
|
default:
|
||||||
|
@ -154,6 +154,7 @@ namespace AssetStudioCLI.Options
|
|||||||
{
|
{
|
||||||
ClassIDType.Texture2D,
|
ClassIDType.Texture2D,
|
||||||
ClassIDType.Sprite,
|
ClassIDType.Sprite,
|
||||||
|
ClassIDType.AkPortraitSprite,
|
||||||
ClassIDType.TextAsset,
|
ClassIDType.TextAsset,
|
||||||
ClassIDType.MonoBehaviour,
|
ClassIDType.MonoBehaviour,
|
||||||
ClassIDType.Font,
|
ClassIDType.Font,
|
||||||
@ -184,8 +185,8 @@ namespace AssetStudioCLI.Options
|
|||||||
optionDefaultValue: supportedAssetTypes,
|
optionDefaultValue: supportedAssetTypes,
|
||||||
optionName: "-t, --asset-type <value(s)>",
|
optionName: "-t, --asset-type <value(s)>",
|
||||||
optionDescription: "Specify asset type(s) to export\n" +
|
optionDescription: "Specify asset type(s) to export\n" +
|
||||||
"<Value(s): tex2d, sprite, textAsset, monoBehaviour, font, shader, movieTexture,\n" +
|
"<Value(s): tex2d, sprite, akPortrait, textAsset, monoBehaviour, font, shader,\n" +
|
||||||
"audio, video, mesh | all(default)>\n" +
|
"movieTexture, audio, video, mesh | all(default)>\n" +
|
||||||
"All - export all asset types, which are listed in the values\n" +
|
"All - export all asset types, which are listed in the values\n" +
|
||||||
"*To specify multiple asset types, write them separated by ',' or ';' without spaces\n" +
|
"*To specify multiple asset types, write them separated by ',' or ';' without spaces\n" +
|
||||||
"Examples: \"-t sprite\" or \"-t tex2d,sprite,audio\" or \"-t tex2d;sprite;font\"\n",
|
"Examples: \"-t sprite\" or \"-t tex2d,sprite,audio\" or \"-t tex2d;sprite;font\"\n",
|
||||||
@ -532,6 +533,9 @@ namespace AssetStudioCLI.Options
|
|||||||
case "sprite":
|
case "sprite":
|
||||||
o_exportAssetTypes.Value.Add(ClassIDType.Sprite);
|
o_exportAssetTypes.Value.Add(ClassIDType.Sprite);
|
||||||
break;
|
break;
|
||||||
|
case "akportrait":
|
||||||
|
o_exportAssetTypes.Value.Add(ClassIDType.AkPortraitSprite);
|
||||||
|
break;
|
||||||
case "textasset":
|
case "textasset":
|
||||||
o_exportAssetTypes.Value.Add(ClassIDType.TextAsset);
|
o_exportAssetTypes.Value.Add(ClassIDType.TextAsset);
|
||||||
break;
|
break;
|
||||||
@ -959,10 +963,10 @@ namespace AssetStudioCLI.Options
|
|||||||
sb.AppendLine($"# Asset Group Option: {o_groupAssetsBy}");
|
sb.AppendLine($"# Asset Group Option: {o_groupAssetsBy}");
|
||||||
sb.AppendLine($"# Export Image Format: {o_imageFormat}");
|
sb.AppendLine($"# Export Image Format: {o_imageFormat}");
|
||||||
sb.AppendLine($"# Export Audio Format: {o_audioFormat}");
|
sb.AppendLine($"# Export Audio Format: {o_audioFormat}");
|
||||||
sb.AppendLine($"# [Arkingths] Sprite Mode: {o_akSpriteMaskMode}");
|
sb.AppendLine($"# [Arkingths] Sprite Mask Mode: {o_akSpriteMaskMode}");
|
||||||
sb.AppendLine($"# [Arknights] Mask Resampler: {resamplerName}");
|
sb.AppendLine($"# [Arknights] Mask Resampler: {resamplerName}");
|
||||||
sb.AppendLine($"# [Arknights] Mask Gamma Correction: {o_akAlphaMaskGamma.Value * 10:+#;-#;0}%");
|
sb.AppendLine($"# [Arknights] Mask Gamma Correction: {o_akAlphaMaskGamma.Value * 10:+#;-#;0}%");
|
||||||
sb.AppendLine($"# [Arknights] Original Avg Names: {f_akOriginalAvgNames}");
|
sb.AppendLine($"# [Arknights] Don't Fix Avg Names: {f_akOriginalAvgNames}");
|
||||||
sb.AppendLine($"# [Arknights] Add Aliases: {f_akAddAliases}");
|
sb.AppendLine($"# [Arknights] Add Aliases: {f_akAddAliases}");
|
||||||
sb.AppendLine($"# Log Level: {o_logLevel}");
|
sb.AppendLine($"# Log Level: {o_logLevel}");
|
||||||
sb.AppendLine($"# Log Output: {o_logOutput}");
|
sb.AppendLine($"# Log Output: {o_logOutput}");
|
||||||
|
@ -145,6 +145,15 @@ namespace AssetStudioCLI
|
|||||||
if (containers.ContainsKey(asset.Asset))
|
if (containers.ContainsKey(asset.Asset))
|
||||||
{
|
{
|
||||||
asset.Container = containers[asset.Asset];
|
asset.Container = containers[asset.Asset];
|
||||||
|
|
||||||
|
if (asset.Type == ClassIDType.MonoBehaviour && asset.Container.Contains("/arts/charportraits/portraits"))
|
||||||
|
{
|
||||||
|
var portraitsList = Arknights.AkSpriteHelper.GeneratePortraits(asset);
|
||||||
|
foreach (var portrait in portraitsList)
|
||||||
|
{
|
||||||
|
exportableAssetsList.Add(new AssetItem(portrait));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CLIOptions.o_workMode.Value != WorkMode.ExportLive2D)
|
if (CLIOptions.o_workMode.Value != WorkMode.ExportLive2D)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user