【Unity】スクリーンショットを保存する

こじゃら
こじゃら

ねえねえ、Unityで作っているゲームのスクリーンショットを手軽に保存する方法はないの~?

このは
このは

スクリプトを書く必要があるけど、実現可能だわ!
一度スクリプトを作っておけば使いまわせるから、ここでマスターしていってね。

本記事では、UnityEditor上で実行しているゲームのスクリーンショットを保存する方法をご紹介させていただきます。

画面全体のスクリーンショットを保存する

実行中のゲームの画面全体のスクリーンショットは、ScreenCapture.CaptureScreenshot()メソッドの呼び出しだけで行えます。

ScreenCapture.CaptureScreenshot("Path/To/File/ScreenShot.png");

引数には保存したいスクリーンショットの画像ファイルパスを指定します。
画像はPNG形式で保存されますが、ファイルの拡張子は自分で付ける必要があります。

他にも高解像度指定などオプション指定もできますが、ここでは説明を割愛させていただきます。
詳細は、公式マニュアルをご覧ください。

以下、スペースキーを押したらスクリーンショットが保存されるサンプルです。

サンプルスクリプト

ScreenShotCapturer.cs

using UnityEngine;

/// <summary>
/// スクリーンショットをキャプチャするサンプル
/// </summary>
public class ScreenShotCapturer : MonoBehaviour
{
    private void Update()
    {
        // スペースキーが押されたら
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // スクリーンショットを保存
            CaptureScreenShot("ScreenShot.png");
        }
    }

    // 画面全体のスクリーンショットを保存する
    private void CaptureScreenShot(string filePath)
    {
        ScreenCapture.CaptureScreenshot(filePath);
    }
}

このスクリプトを適当なゲームオブジェクトにアタッチし、ゲームを実行した状態でスペースキーを押すと、Unityプロジェクトディレクトリ直下にScreenShot.pngというファイルが保存されます。

また、スクリーンショットの解像度は実行中のゲーム画面の解像度になる点に注意してください。

実行結果

特定カメラのスクリーンショットを保存する

指定されたカメラが映す内容だけを保存する方法のご紹介です。
オーバーレイで表示されるuGUIコンテンツを除いたスクリーンショットを保存できます。

この場合、上で紹介したメソッドは使えず、カメラの描画先を一時的にRenderTextureに設定してその内容のバイナリデータを取得して保存という面倒なプロセスを踏む必要があります。

以下サンプルです。

サンプルスクリプト

CameraScreenShotCapturer.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

/// <summary>
/// 指定されたカメラの内容をキャプチャするサンプル
/// </summary>
public class CameraScreenShotCapturer : MonoBehaviour
{
    [SerializeField] private Camera _camera;

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            CaptureScreenShot("CameraScreenShot.png");
        }
    }

    // カメラのスクリーンショットを保存する
    private void CaptureScreenShot(string filePath)
    {
        var rt = new RenderTexture(_camera.pixelWidth, _camera.pixelHeight, 24);
        var prev = _camera.targetTexture;
        _camera.targetTexture = rt;
        _camera.Render();
        _camera.targetTexture = prev;
        RenderTexture.active = rt;
        
        var screenShot = new Texture2D(
            _camera.pixelWidth,
            _camera.pixelHeight,
            TextureFormat.RGB24,
            false);
        screenShot.ReadPixels(new Rect(0, 0, screenShot.width, screenShot.height), 0, 0);
        screenShot.Apply();
            
        var bytes = screenShot.EncodeToPNG();
        Destroy(screenShot);
            
        File.WriteAllBytes(filePath, bytes);
    }
}

こちらも同様に適当なオブジェクトにアタッチし、Cameraにスクリーンショットとして保存したい対象カメラを指定して実行し、スペースキーを押すと、そのカメラの内容が保存されます。

実行結果

特定カメラの表示内容のみを保存するため、uGUIテキストが除外されています。

ここで、複数のカメラを用いる場合、Depthの値はそれぞれ異なる設定にしておく必要があります。
Depthが同じだと、スクリーンショットを保存したときにそのカメラがアクティブに切り替わってしまうことがあるためです。

さいごに

2つ目の方法は少々面倒ではあるものの、スクリプトの使いまわしで活用できるため、一度作ってしまえば楽になる事でしょう。
用途に合わせて使い分けて頂ければと思います。

また、本記事のサンプルでは、ファイル名のリビジョン等の考慮は入れていません。
必要に応じてカスタマイズしてお使いください。

参考サイト