本日は Unity の小ネタ枠です。
Unityアプリで画面のキャプチャを保存する方法について記事にします。
UnityEngine.ScreenCapture.CaptureScreenshot
ScreenCapture.CaptureScreenshot を利用すると PNG ファイルとしてスクリーンショットが撮影・保存されます。
docs.unity3d.com
こちらはアプリの現在の映像がそのまま撮影されて保存されます。
以下のサンプルスクリプトを作成しました。ボタンを押下したとき、本スクリプトが実行されてキャプチャが行われます。
・ScreenshotTest.cs
using System; using System.IO; using System.Threading; using Cysharp.Threading.Tasks; using UnityEngine; public class ScreenshotTest : MonoBehaviour { private Camera captureCamera; /// <summary> /// キャプチャの実行関数 /// </summary> public void Capture() { CaptureScreenshotByUnityEngine(); } private void Start() { captureCamera = Camera.main; } private void CaptureScreenshotByUnityEngine() { var date = DateTime.Now.ToString("yyyyMMdd"); string filename = $"screenCapture_{date}.png"; string path = Path.Combine(Application.persistentDataPath,filename); // スクリーンショットを撮影して保存する Debug.Log($"ScreenCapture File : {path}"); File.Delete(path); ScreenCapture.CaptureScreenshot(path); } }
撮影された画像は以下のようになります。
RenderTexture
RenderTexture を使って指定のカメラの描画領域を画像として保存することもできます。
docs.unity3d.com
こちらは通常のレンダーパイプラインを通して描画された映像を保存するため、オーバレイのUIは画像に保存されません。
(ワールドスペースのUIなどは通常のレンダーパイプラインを通るため描画されます)
以下のサンプルスクリプトを作成しました。ボタンを押下したとき、本スクリプトが実行されてキャプチャが行われます。
・ScreenshotTest.cs
using System; using System.IO; using System.Threading; using Cysharp.Threading.Tasks; using UnityEngine; public class ScreenshotTest : MonoBehaviour { private Camera captureCamera; /// <summary> /// キャプチャの実行関数 /// </summary> public void Capture() { CaptureScreenshotByRenderTexture(); } private void Start() { captureCamera = Camera.main; } private void CaptureScreenshotByRenderTexture() { var ct = this.GetCancellationTokenOnDestroy(); CaptureScreenshotByRenderTextureAsync(ct).Forget(); } private async UniTask CaptureScreenshotByRenderTextureAsync(CancellationToken ct) { // 任意のフレームの描画処理が終わるまで待機する await UniTask.WaitForEndOfFrame(ct); // Cameraの描画領域をRenderTextureとして取り出す var rt = new RenderTexture(captureCamera.pixelWidth, captureCamera.pixelHeight, 24); var prev = captureCamera.targetTexture; captureCamera.targetTexture = rt; captureCamera.Render(); captureCamera.targetTexture = prev; RenderTexture.active = rt; var screenShot = new Texture2D( captureCamera.pixelWidth, captureCamera.pixelHeight, TextureFormat.RGB24, false); screenShot.ReadPixels(new Rect(0, 0, screenShot.width, screenShot.height), 0, 0); screenShot.Apply(); // 取り出したTexture2DをPNGに変換して保存する var date = DateTime.Now.ToString("yyyyMMdd"); string filename = $"capture_{date}.png"; var png = screenShot.EncodeToPNG(); string path = Path.Combine(Application.persistentDataPath,filename); File.WriteAllBytes(path, png); Debug.Log($"Capture File : {path}"); } }
撮影された画像は以下のようになります。
UI のボタンが含まれていないことが分かります。