FM/Assets/Test/UIToTextureExporter.cs

82 lines
2.6 KiB
C#
Raw Normal View History

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using System.IO;
/// <summary>
/// pass
/// </summary>
public class UIToTextureExporter : MonoBehaviour
{
public RectTransform targetUIRoot;
public Vector2Int outputResolution = new Vector2Int(1024, 1024);
public string fileName = "UIRender";
public string saveFolder = "Exports";
[ContextMenu("导出 UI 图像")]
public void ExportUI()
{
if (targetUIRoot == null)
{
Debug.LogError("请指定 UI 根节点!");
return;
}
// 创建RenderTexture
RenderTexture rt = new RenderTexture(outputResolution.x, outputResolution.y, 24);
RenderTexture.active = rt;
// 清空背景
GL.Clear(true, true, new Color(0, 0, 0, 0));
// 创建一个临时Canvas进行渲染
GameObject tempCanvasGO = new GameObject("TempCanvas", typeof(Canvas));
Canvas tempCanvas = tempCanvasGO.GetComponent<Canvas>();
tempCanvas.renderMode = RenderMode.WorldSpace;
tempCanvas.pixelPerfect = true;
RectTransform canvasRT = tempCanvas.GetComponent<RectTransform>();
canvasRT.sizeDelta = outputResolution;
// 拷贝所有 Graphic 元素
List<Graphic> graphics = new List<Graphic>();
targetUIRoot.GetComponentsInChildren(true, graphics);
foreach (var graphic in graphics)
{
if (!graphic.gameObject.activeInHierarchy) continue;
var clone = Instantiate(graphic, tempCanvas.transform);
var rect = clone.rectTransform;
// 保持位置、尺寸
rect.sizeDelta = graphic.rectTransform.rect.size;
rect.anchoredPosition = graphic.rectTransform.anchoredPosition;
rect.localScale = graphic.rectTransform.localScale;
}
// 强制渲染一次
Canvas.ForceUpdateCanvases();
// 生成截图
Texture2D result = new Texture2D(outputResolution.x, outputResolution.y, TextureFormat.ARGB32, false);
result.ReadPixels(new Rect(0, 0, outputResolution.x, outputResolution.y), 0, 0);
result.Apply();
// 保存
string dirPath = Path.Combine(Application.dataPath, saveFolder);
Directory.CreateDirectory(dirPath);
string path = Path.Combine(dirPath, fileName + ".png");
File.WriteAllBytes(path, result.EncodeToPNG());
Debug.Log($"✅ UI导出成功{path}");
// 清理
DestroyImmediate(result);
DestroyImmediate(tempCanvasGO);
RenderTexture.active = null;
rt.Release();
DestroyImmediate(rt);
}
}