Unity的截屏保存功能
在制作游戏时,想在玩家保存游戏进度时,记录当前的游戏界面,这就需要用到截屏保存图片的功能
在截屏的时候,同时隐藏UI
方法一:临时禁用Canvas(最简单)
using UnityEngine;
public class ScreenshotWithoutUI : MonoBehaviour
{
public Canvas[] canvasesToHide; // 需要隐藏的Canvas
public KeyCode captureKey = KeyCode.Print;
public string savePath = "Screenshots/";
public string fileNamePrefix = "Screenshot_";
void Update()
{
if (Input.GetKeyDown(captureKey))
{
StartCoroutine(CaptureAndSave());
}
}
private IEnumerator CaptureAndSave()
{
// 隐藏所有Canvas
foreach (var canvas in canvasesToHide)
{
canvas.enabled = false;
}
var folder = Application.persistentDataPath + "/" + savePath;
// 创建保存目录(如果不存在)
System.IO.Directory.CreateDirectory(folder);
// 生成带时间戳的文件名
var timestamp = System.DateTime.Now.ToString("yyyyMMdd_HHmmss");
var filePath = $"{folder}{fileNamePrefix}{timestamp}.png";
// 等待一帧确保UI已隐藏
yield return null;
// 截屏并保存
ScreenCapture.CaptureScreenshot(filePath);
// 恢复显示Canvas
yield return new WaitForEndOfFrame();
foreach (var canvas in canvasesToHide)
{
canvas.enabled = true;
}
Debug.Log($"截屏已保存至: {filePath}");
}
}
方法二:使用RenderTexture(高性能)
这种方法通过相机单独渲染游戏内容,不包含UI层。
using UnityEngine;
public class RenderTextureScreenshot : MonoBehaviour
{
public Camera mainCamera; // 主相机
public Canvas uiCanvas; // UI Canvas
public KeyCode captureKey = KeyCode.Space;
public string savePath = "Screenshots/";
private RenderTexture renderTexture;
void Start()
{
// 创建与屏幕尺寸匹配的RenderTexture
renderTexture = new RenderTexture(Screen.width, Screen.height, 24);
mainCamera.targetTexture = renderTexture;
}
void Update()
{
if (Input.GetKeyDown(captureKey))
{
CaptureScreenshot();
}
}
void CaptureScreenshot()
{
// 临时禁用UI相机
uiCanvas.worldCamera.enabled = false;
// 渲染场景到RenderTexture
mainCamera.Render();
// 读取RenderTexture内容
Texture2D screenShot = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
RenderTexture.active = renderTexture;
screenShot.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
screenShot.Apply();
// 恢复UI相机
uiCanvas.worldCamera.enabled = true;
// 保存图片
byte[] bytes = screenShot.EncodeToPNG();
System.IO.File.WriteAllBytes(savePath + "screenshot.png", bytes);
// 清理资源
Destroy(screenShot);
}
}
方法三:分层渲染(推荐方案)
通过设置相机的Culling Mask,让主相机只渲染游戏内容,UI相机单独渲染UI。
步骤:
-
创建图层:
- 创建一个新图层(如"UI"),将所有UI元素移到该图层。
-
配置相机:
- 主相机:取消勾选"UI"图层。
- UI相机:只勾选"UI"图层,并设置为"Screen Space - Camera"模式。
-
截图代码:
using UnityEngine;
public class LayeredScreenshot : MonoBehaviour
{
public Camera uiCamera; // UI相机
public KeyCode captureKey = KeyCode.Space;
void Update()
{
if (Input.GetKeyDown(captureKey))
{
StartCoroutine(Capture());
}
}
System.Collections.IEnumerator Capture()
{
// 禁用UI相机
uiCamera.enabled = false;
// 等待一帧确保UI已隐藏
yield return null;
// 截屏
ScreenCapture.CaptureScreenshot("screenshot.png");
// 恢复UI相机
yield return new WaitForEndOfFrame();
uiCamera.enabled = true;
}
}
使用建议
- 性能对比:方法二(RenderTexture)和方法三(分层渲染)对性能影响较小,适合频繁截图的场景。
- UI恢复:确保在截图完成后恢复UI显示,避免用户体验中断。
- 动态UI:如果UI是动态生成的,建议通过代码动态获取所有Canvas组件。
扩展功能
1. 只隐藏部分UI
// 隐藏特定UI元素而非整个Canvas
public GameObject[] uiElementsToHide;
foreach (var element in uiElementsToHide)
{
element.SetActive(false);
}
2. 截图时显示临时提示
public GameObject captureHint;
// 截图前显示提示
captureHint.SetActive(true);
// 截图后隐藏提示
captureHint.SetActive(false);