Files
HX_MapEditor/Assets/Scripts/SpritesGenerator/MultiGroupSpriteMerger.cs
2025-07-11 01:26:27 +08:00

148 lines
4.8 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using SFB;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
public class MultiGroupSpriteMerger : MonoBehaviour
{
public Button selectFolderButton;
public Text statusText;
void Start()
{
selectFolderButton.onClick.AddListener(OnSelectFolder);
}
void OnSelectFolder()
{
var paths = StandaloneFileBrowser.OpenFolderPanel("选择包含序列帧图片的文件夹", "", false);
if (paths.Length > 0)
{
ProcessAllGroups(paths[0]);
}
}
void ProcessAllGroups(string folderPath)
{
statusText.text = "开始读取图片...";
string[] files = Directory.GetFiles(folderPath, "*.png");
Dictionary<int, Dictionary<int, List<Texture2D>>> groupMap = new();
Regex regex = new Regex(@"(\d+)_(\d+)\.png");
foreach (var path in files)
{
string fileName = Path.GetFileName(path);
Match match = regex.Match(fileName);
if (!match.Success) continue;
int x = int.Parse(match.Groups[1].Value);
int groupIndex = (x - 1) / 8 + 1;
int direction = (x - 1) % 8 + 1;
Texture2D tex = new Texture2D(2, 2);
if (!tex.LoadImage(File.ReadAllBytes(path)))
{
Debug.LogWarning($"加载图片失败: {fileName}");
continue;
}
tex.name = fileName;
if (!groupMap.ContainsKey(groupIndex))
groupMap[groupIndex] = new Dictionary<int, List<Texture2D>>();
if (!groupMap[groupIndex].ContainsKey(direction))
groupMap[groupIndex][direction] = new List<Texture2D>();
groupMap[groupIndex][direction].Add(tex);
}
int exportedCount = 0;
foreach (var group in groupMap)
{
int groupId = group.Key;
var directions = group.Value;
List<int> rowHeights = new();
List<List<Texture2D>> rows = new();
List<int> rowWidths = new();
foreach (var dir in directions)
{
var frames = dir.Value;
int maxH = 0, totalW = 0;
// 排序帧
frames.Sort((a, b) =>
{
var ma = Regex.Match(a.name, @"\d+_(\d+)");
var mb = Regex.Match(b.name, @"\d+_(\d+)");
return int.Parse(ma.Groups[1].Value).CompareTo(int.Parse(mb.Groups[1].Value));
});
foreach (var tex in frames)
{
totalW += tex.width;
maxH = Mathf.Max(maxH, tex.height);
}
rowWidths.Add(totalW);
rowHeights.Add(maxH);
rows.Add(frames);
}
int totalHeight = 0;
foreach (int h in rowHeights) totalHeight += h;
int totalWidth = 0;
foreach (int w in rowWidths) totalWidth = Mathf.Max(totalWidth, w);
Texture2D result = new Texture2D(totalWidth, totalHeight, TextureFormat.RGBA32, false);
Color[] clear = new Color[totalWidth * totalHeight];
for (int i = 0; i < clear.Length; i++) clear[i] = new Color(0, 0, 0, 0);
result.SetPixels(clear);
int yOffset = totalHeight;
for (int row = 0; row < rows.Count; row++)
{
List<Texture2D> frames = rows[row];
int xOffset = 0;
int rowHeight = rowHeights[row];
yOffset -= rowHeight;
foreach (var tex in frames)
{
try
{
Color[] pixels = tex.GetPixels();
if (pixels.Length != tex.width * tex.height)
{
Debug.LogWarning($"跳过尺寸异常图像: {tex.name}");
continue;
}
result.SetPixels(xOffset, yOffset + (rowHeight - tex.height), tex.width, tex.height, pixels);
xOffset += tex.width;
}
catch (System.Exception ex)
{
Debug.LogError($"绘图出错: {tex.name} - {ex.Message}");
}
}
}
result.Apply();
string savePath = Path.Combine(folderPath, $"combined_group_{groupId}.png");
File.WriteAllBytes(savePath, result.EncodeToPNG());
Debug.Log($"导出完成:{savePath}");
exportedCount++;
}
statusText.text = $"完成,共导出 {exportedCount} 张大图";
}
}