UpdatePSB_UGUI

This commit is contained in:
2025-12-11 17:44:10 +08:00
parent f8947c6c27
commit 84227a6686
2 changed files with 80 additions and 57 deletions
@@ -20,11 +20,14 @@ public class PsbToUGUIWindow : EditorWindow
private bool autoCreateCanvasIfMissing = true;
private string parentName = "PSB_UI";
// 新增 Toggle
private bool exportAsPng = false;
[MenuItem("Tools/PSB → UGUI Converter")]
public static void ShowWindow()
{
var win = GetWindow<PsbToUGUIWindow>("PSB → UGUI");
win.minSize = new Vector2(420, 320);
win.minSize = new Vector2(420, 360);
}
private void OnGUI()
@@ -70,6 +73,12 @@ public class PsbToUGUIWindow : EditorWindow
parentName
);
// 新增 Toggle
exportAsPng = EditorGUILayout.Toggle(
new GUIContent("Export sprites as PNG", "If checked, each sprite will be exported as a PNG file"),
exportAsPng
);
EditorGUILayout.Space();
using (new EditorGUI.DisabledScope(sourceRoot == null))
@@ -158,7 +167,7 @@ public class PsbToUGUIWindow : EditorWindow
mapping[t] = rt;
}
// Create UI Images for SpriteRenderers and export PNG files
// Create UI Images for SpriteRenderers
foreach (var kv in mapping.ToList())
{
var src = kv.Key;
@@ -168,62 +177,74 @@ public class PsbToUGUIWindow : EditorWindow
if (sr == null || sr.sprite == null)
continue;
Object prefab = PrefabUtility.GetCorrespondingObjectFromSource(sourceRoot);
string psbPath = AssetDatabase.GetAssetPath(prefab);
if (string.IsNullOrEmpty(psbPath))
Sprite copiedSprite = null;
if (exportAsPng)
{
psbPath = AssetDatabase.GetAssetPath(sr.sprite);
// ===== 导出 PNG 文件 =====
Object prefab = PrefabUtility.GetCorrespondingObjectFromSource(sourceRoot);
string psbPath = AssetDatabase.GetAssetPath(prefab);
if (string.IsNullOrEmpty(psbPath))
{
psbPath = AssetDatabase.GetAssetPath(sr.sprite);
}
string psbFolder = Path.GetDirectoryName(psbPath);
if (string.IsNullOrEmpty(psbFolder))
{
Debug.LogError($"无法获取有效的 psb 文件夹路径,源对象: {sourceRoot.name}");
continue;
}
string psbName = Path.GetFileNameWithoutExtension(psbPath);
string targetFolder = Path.Combine(psbFolder, psbName);
if (!AssetDatabase.IsValidFolder(targetFolder))
{
AssetDatabase.CreateFolder(psbFolder, psbName);
}
// 使用 RenderTexture 拷贝再导出 PNG
Sprite srcSprite = sr.sprite;
Texture2D srcTex = srcSprite.texture;
Rect rect = srcSprite.rect;
int w = Mathf.RoundToInt(rect.width);
int h = Mathf.RoundToInt(rect.height);
RenderTexture rt = RenderTexture.GetTemporary(srcTex.width, srcTex.height, 0);
Graphics.Blit(srcTex, rt);
RenderTexture.active = rt;
Texture2D outTex = new Texture2D(w, h, TextureFormat.RGBA32, false);
outTex.ReadPixels(new Rect(rect.x, rect.y, rect.width, rect.height), 0, 0);
outTex.Apply();
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(rt);
byte[] pngData = outTex.EncodeToPNG();
string pngPath = Path.Combine(targetFolder, srcSprite.name + ".png");
pngPath = AssetDatabase.GenerateUniqueAssetPath(pngPath);
File.WriteAllBytes(pngPath, pngData);
AssetDatabase.ImportAsset(pngPath);
var texImp = AssetImporter.GetAtPath(pngPath) as TextureImporter;
if (texImp != null)
{
texImp.textureType = TextureImporterType.Sprite;
texImp.spritePixelsPerUnit = referencePPU;
texImp.alphaIsTransparency = true;
texImp.spritePivot = srcSprite.pivot / new Vector2(rect.width, rect.height);
texImp.SaveAndReimport();
}
copiedSprite = AssetDatabase.LoadAssetAtPath<Sprite>(pngPath);
}
else
{
// ===== 保持原始 psb sprite =====
copiedSprite = sr.sprite;
}
string psbFolder = Path.GetDirectoryName(psbPath);
if (string.IsNullOrEmpty(psbFolder))
{
Debug.LogError($"无法获取有效的 psb 文件夹路径,源对象: {sourceRoot.name}");
continue;
}
string psbName = Path.GetFileNameWithoutExtension(psbPath);
string targetFolder = Path.Combine(psbFolder, psbName);
if (!AssetDatabase.IsValidFolder(targetFolder))
{
AssetDatabase.CreateFolder(psbFolder, psbName);
}
// 使用 RenderTexture 拷贝再导出 PNG
Sprite srcSprite = sr.sprite;
Texture2D srcTex = srcSprite.texture;
Rect rect = srcSprite.rect;
int w = Mathf.RoundToInt(rect.width);
int h = Mathf.RoundToInt(rect.height);
RenderTexture rt = RenderTexture.GetTemporary(srcTex.width, srcTex.height, 0);
Graphics.Blit(srcTex, rt);
RenderTexture.active = rt;
Texture2D outTex = new Texture2D(w, h, TextureFormat.RGBA32, false);
outTex.ReadPixels(new Rect(rect.x, rect.y, rect.width, rect.height), 0, 0);
outTex.Apply();
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(rt);
byte[] pngData = outTex.EncodeToPNG();
string pngPath = Path.Combine(targetFolder, srcSprite.name + ".png");
pngPath = AssetDatabase.GenerateUniqueAssetPath(pngPath);
File.WriteAllBytes(pngPath, pngData);
AssetDatabase.ImportAsset(pngPath);
var texImp = AssetImporter.GetAtPath(pngPath) as TextureImporter;
if (texImp != null)
{
texImp.textureType = TextureImporterType.Sprite;
texImp.spritePixelsPerUnit = referencePPU;
texImp.alphaIsTransparency = true;
texImp.spritePivot = srcSprite.pivot / new Vector2(rect.width, rect.height);
texImp.SaveAndReimport();
}
Sprite copiedSprite = AssetDatabase.LoadAssetAtPath<Sprite>(pngPath);
// Add Image
var img = dstRT.gameObject.AddComponent<Image>();
img.sprite = copiedSprite;
img.preserveAspect = false;
@@ -237,7 +258,7 @@ public class PsbToUGUIWindow : EditorWindow
}
img.SetNativeSize();
dstRT.pivot = copiedSprite.pivot / new Vector2(rect.width, rect.height);
dstRT.pivot = copiedSprite.pivot / new Vector2(copiedSprite.rect.width, copiedSprite.rect.height);
}
if (preserveSortingOrder)
@@ -271,6 +292,8 @@ public class PsbToUGUIWindow : EditorWindow
Selection.activeObject = uiRootGO;
EditorGUIUtility.PingObject(uiRootGO);
Debug.Log("PSB → UGUI conversion completed (sprites exported as PNG and assigned).");
Debug.Log(exportAsPng
? "PSB → UGUI conversion completed (sprites exported as PNG and assigned)."
: "PSB → UGUI conversion completed (using original psb sprites).");
}
}