概要
UnityEdito上でスクリーンショットを取る方法について説明します。
大きく分けてUnity Recorderを使う方法と、スクリーンショットを撮るスクリプトを書いて使う方法があります。
この記事ではスクリプトを使う場合のサンプルコードも掲載しています。
※2018年に執筆した時、備忘録程度に雑に描いた記事なのですが…思ったよりも使ってる人が多かったので2022年7月に大幅な記事のリライトを行いました。
【1-1】Unity Recorderの説明
UnityにはUnity RecorderというUnityが作ってる公式のアセットがあります。
こちらを使う事でUnityEditor上で再生されたGameタブをイメージ(JPEG,PNG,EXR)、ムービー(MP4,WebM,QuickTime)、アニメーションクリップ形式、GIF、オーディオ(WAV)、AOV(JPEG,PNG,EXR)で保存できます。
【1-2】Unity Recorderの導入

1.UnityEditorのメニューから「Window」→「PackageManager」を選択して、PackageManagerを開きます。

2.左上のタブを「Unity Registry」に変更した後、右上の検索欄に「Unity Recorder」と入力します。

3.「Unity Recorder」の詳細が表示されてる状態で右下の「Install」を押すことで導入完了です。
【1-3】UnityRecorderの利用

「Window」→「General」→「Recorder」→「RecorderWindow」を開くとRecorderの設定画面が開けます。

大まかな使い方の流れは…
1.「Add Recorder」から撮影したいメディアを追加。
2.設定Windowでメディアの設定を行う。
3.左上の再生ボタンを押すとUnityが実行されて撮影が始まる。
詳細なマニュアルについては下記リンクをご確認ください。
・Recorder ウィンドウからのレコーディング
【2-1】スクリーンショットを撮るスクリプトを書く
using System;
using System.Collections;
using System.IO;
using UnityEngine;
namespace ScreenshotUtility
{
    //タイムスタンプの書式設定
    public enum TIME_STAMP
    {
        MMDDHHMMSS,
        YYYYMMDDHHMMSS,
    }
    //背景色の設定
    public enum BACK_GROUND_COLOR
    {
        Alpha, //透過PNG
        CustomColor, //カスタムカラー
        Skybox, //スカイボックス
    }
    //解像度の設定
    public enum SCREEN_SIZE_PIXEL
    {
        //1:1
        p256x256,
        p512x512,
        p1024x1024,
        p2048x2048,
        p4096x4096,
        //16:9
        p1280x720, //HD
        p1920x1080, //FullHD
        p2560x1440, //2k
        p3840x2160, //4k
        CustomSize //指定したピクセルサイズで出力(下限32/上限4096)
    }
    public class ScreenShot : MonoBehaviour
    {
//UnityEditorのみで実行
#if UNITY_EDITOR
        [Header("撮影に使うカメラの割り当て")]
        [Tooltip("撮影に使うカメラを割り当ててください"), SerializeField]
        Camera _UseCamera;
        [Header("画像のサイズの設定")]
        [Space(10)]
        [Tooltip("ScreenSizePixelをCustomにするとCustomSizeの解像度が適用されます"), SerializeField]
        SCREEN_SIZE_PIXEL _screenSizePixel = SCREEN_SIZE_PIXEL.p1024x1024;
        [Tooltip("ScreenSizePixelがCustomになってる場合の解像度設定(下限32Pixel/上限4096Pixel)"), SerializeField]
        Vector2Int _customSize = new Vector2Int(1024, 1024);
        [Header("背景色の設定")]
        [Space(10)]
        [Tooltip("Alpha:背景透過 White:白 CustomColor:指定した色 Skybox:スカイボックス"), SerializeField]
        BACK_GROUND_COLOR _buckGroundColorType = BACK_GROUND_COLOR.Alpha;
        [Tooltip("BuckGroundColorTypeがCustomの場合の背景色"), SerializeField]
        UnityEngine.Color _customColor = UnityEngine.Color.green;
        [Header("ファイル名の書式設定")]
        [Space(10)]
        [Tooltip("タイムスタンプの書式設定"), SerializeField]
        TIME_STAMP _timeStampStyle = TIME_STAMP.MMDDHHMMSS;
        [Tooltip("ファイル名の先頭に付く文字列"), SerializeField]
        string _screenShotsTitle = "img";
        [Header("保存先のフォルダ名")]
        [Space(10)]
        [Tooltip("スクリーンショットを保存するフォルダ名 Assetsフォルダーの直下に配置されます"), SerializeField]
        string _screenShotFolderName = "ScreenShots";
        [Header("実行中の撮影キー")]
        [Space(10)]
        [Tooltip("Unity実行中にスクリーンショットを撮る場合のキーバインド")]
        public KeyCode _screenShotsKeybinding = KeyCode.F1;
        [Header("Consoleに保存先のパスのログを出力します")]
        [Space(10)]
        [Tooltip("チェックをすると、画像のファイル名と画像の保存先のパスのログの出力します"), SerializeField]
        bool _consoleLogIsActive = true;
        void Update()
        {
            if(Input.GetKeyDown(_screenShotsKeybinding))
            {
                getScreenShots();
            }
        }
        private bool NullCheck()
        {
            bool isNull = false;
            if(_UseCamera == null)
            {
                Debug.LogWarning("画像の書き出しに使用するカメラを ScreenSchotCamera に割り当ててください");
                isNull = true;
            }
            if(_screenShotsTitle == "")
            {
                Debug.LogWarning("ScreenShotsTitle に画像ファイルに付ける末尾の文字を入力してください");
                isNull = true;                
            }
            if(_screenShotFolderName == "")
            {
                Debug.LogWarning("ScreenShotFolderName にScreenShotの保存先のフォルダ名を入力してください");
                isNull = true;                
            }            
            return isNull;
        }
        
        [ContextMenu("スクリーンショットを撮影する")]
        public void getScreenShots()
        {
            //NullCheck
            if(NullCheck()){ return; }
            // Application.dataPath = ../Assets
            string path = UnityEngine.Application.dataPath + "/" + _screenShotFolderName + "/";
            StartCoroutine(imageShooting(path, _screenShotsTitle));
        }
        //撮影処理
        //第一引数 ファイルパス / 第二引数 タイトル
        private IEnumerator imageShooting(string path, string title)
        {
            yield return new WaitForEndOfFrame();
            //パスの作成
            imagePathCheck(path);
            string name = title + getTimeStamp(_timeStampStyle) + ".png";
            //元々の背景色をCache
            Color32 CacheColor = _UseCamera.backgroundColor;
            //背景色:透過
            if(_buckGroundColorType == BACK_GROUND_COLOR.Alpha)
            {
                _UseCamera.backgroundColor = new Color32(0, 0, 0, 0);
                _UseCamera.GetComponent<Camera>().clearFlags = CameraClearFlags.SolidColor;
            }
            //背景色:カスタム
            if(_buckGroundColorType == BACK_GROUND_COLOR.CustomColor)
            {
                _UseCamera.backgroundColor = _customColor;
                _UseCamera.GetComponent<Camera>().clearFlags = CameraClearFlags.SolidColor;
            }
            //背景色:スカイボックス
            if(_buckGroundColorType == BACK_GROUND_COLOR.Skybox)
            {
                _UseCamera.GetComponent<Camera>().clearFlags = CameraClearFlags.Skybox;
            }
            //スクショ作成
            //書き出しサイズの取得
            Vector2Int size = getScreenSizePixel2Int(_screenSizePixel);
            Texture2D screenShot = new Texture2D(size.x, size.y, TextureFormat.ARGB32, false);
            RenderTexture rt = new RenderTexture(screenShot.width, screenShot.height, 32);
            RenderTexture prev = _UseCamera.targetTexture;
            _UseCamera.targetTexture = rt;
            _UseCamera.Render();
            _UseCamera.targetTexture = prev;
            RenderTexture.active = rt;
            screenShot.ReadPixels(new Rect(0, 0, screenShot.width, screenShot.height), 0, 0);
            screenShot.Apply();
            byte[] bytes = screenShot.EncodeToPNG();
            //UnityEngine.Object.Destroy(screenShot);
            //書き込み
            File.WriteAllBytes(path + name, bytes);
            //ログの表示
            if(_consoleLogIsActive)
            {
                Debug.Log("Title: " + name);
                Debug.Log("Directory: " + path);
            }
            //カメラの背景色を元に戻す
            _UseCamera.backgroundColor = CacheColor;
            //Assetフォルダのリロード
            UnityEditor.AssetDatabase.Refresh();
        }
        //ファイルパスの確認
        private void imagePathCheck(string path)
        {
            if (Directory.Exists(path))
            {
                //Debug.Log("The path exists");
            }
            else
            {
                //パスが存在しなければフォルダを作成
                Directory.CreateDirectory(path);
                Debug.Log("CreateFolder: " + path);
            }
        }
        private Vector2Int getScreenSizePixel2Int(SCREEN_SIZE_PIXEL ScreenSize)
        {
            //デフォルト設定
            Vector2Int size = new Vector2Int(1024, 1024);
            switch(ScreenSize)
            {
                //1:1(正方形)
                case SCREEN_SIZE_PIXEL.p256x256:
                    size = new Vector2Int(256, 256);
                    break;                
                case SCREEN_SIZE_PIXEL.p512x512:
                    size = new Vector2Int(512, 512);
                    break;
                case SCREEN_SIZE_PIXEL.p1024x1024:
                    size = new Vector2Int(1024, 1024);
                    break;
                case SCREEN_SIZE_PIXEL.p2048x2048:
                    size = new Vector2Int(2048, 2048);
                    break;
                case SCREEN_SIZE_PIXEL.p4096x4096:
                    size = new Vector2Int(4096, 4096);
                    break;
                //16:9
                case SCREEN_SIZE_PIXEL.p1280x720:
                    size = new Vector2Int(1280, 720);
                    break;
                case SCREEN_SIZE_PIXEL.p1920x1080:
                    size = new Vector2Int(1920, 1080);
                    break;
                case SCREEN_SIZE_PIXEL.p2560x1440:
                    size = new Vector2Int(2560, 1440);
                    break;
                case SCREEN_SIZE_PIXEL.p3840x2160:
                    size = new Vector2Int(3840, 2160);
                    break;
                //CustomscreenSize
                case SCREEN_SIZE_PIXEL.CustomSize:
                    //UpperLimit
                    if(_customSize.x > 4096)
                    {
                        _customSize.x = 4096;
                        Debug.LogWarning("PixelSizeのXを4096に設定しました。");
                    }
                    if(_customSize.y > 4096)
                    {
                        _customSize.y = 4096;
                        Debug.LogWarning("PixelSizeのYを4096に設定しました。");
                    }
                    //UnderLimit
                    if(_customSize.x < 32)
                    {
                        _customSize.x = 32;
                        Debug.LogWarning("PixelSizeのXを32に設定しました。");
                    }
                    if(_customSize.y < 32)
                    {
                        _customSize.y = 32;
                        Debug.LogWarning("PixelSizeのYを32に設定しました。");
                    }
                    size = _customSize;
                    break;                
                //設定されてないSCREEN_SIZE_PIXELが選択された場合
                default:
                    Debug.LogWarning("設定されてないSCREEN_SIZE_PIXELが選択されました。");
                    Debug.LogWarning("解像度 " + size + " で書き出します。");
                    break;
            }
            return size;
        }
        //タイムスタンプ
        private string getTimeStamp(TIME_STAMP type)
        {
            string time;
            //タイムスタンプの設定書き足せます
            switch (type)
            {
                case TIME_STAMP.MMDDHHMMSS:
                    time = DateTime.Now.ToString("MMddHHmmss");
                    return time;
                case TIME_STAMP.YYYYMMDDHHMMSS:
                    time = DateTime.Now.ToString("yyyyMMddHHmmss");
                    return time;
                default:
                    time = DateTime.Now.ToString("yyyyMMddHHmmss");
                    return time;
            }
        }
#endif
    }
}
【2-2】プロジェクトへの導入
1.UnityEditorのProjectタブでメニューを出して「Create」→「C# Script」でScriptを作成します。
 Scriptのファイル名は必ず「ScreenShot」にしてください。別名なだとエラーになります。
2.作成したC#のファイルを開いて、全て削除した後に上記のサンプルコードを全て上書きします。
 using System;の行から } で終わってる行まで全てコピペしてください。
3.ScreenShotのスクリプトを適当なゲームオブジェクトにアタッチしてください。
【2-3】使い方
1.UseCameraの部分に撮影に使うCameraを割り当ててください。
2.実行中の場合は F1キーで撮影 実行中じゃない場合も歯車アイコンからメニューを開いて「スクリーンショットを撮影する」を押すと撮影できます。
ScreenSizePixel
プリセットをいくつか用意しました。プリセットに無い場合はCustomSizeを選択して、CustomSizeの欄に画像の解像度を入力してください。
最大解像度は4096、最小解像度は32に制限してあります。
背景色の設定
背景色はAlpha(透明)、CustomColor(選択した色)、Skybox(スカイボックスを撮影する)の3種類から設定できます。
ファイル名の書式設定
タイムスタンプの形式と末尾の文字列を変更できます。
他の書式にする場合はソースコードを直接編集してください。
保存先のフォルダ名
Assetsフォルダ以下に配置されます。(存在しない場合は自動で作成されます)
Gameタブの解像度を指定する方法

1.Gameタブのあの部分をクリックするとメニューが展開される。
2.+から「Add New Item」を押す。
3.ウインドウでLabel (名前) Width&Height (縦横の解像度)を設定する。
4.プリセットに追加されるので、任意の解像度にできる。
Vtuberの用途的には、Youtubeの基本の解像度を入れておくとよいと思います。
また 128x128 や 1024x1024 等も入れておくと、アイコン作成やテクスチャ作成時に便利です。
参考:【Unity】高解像度のゲーム画面向けにゲームビューを調整する
参考:Youtubeで推奨される解像度とアスペクト比
カメラを移動しながら撮影したい。
【Unity】カメラ移動を制御するスクリプト
上記を参考にしてみてください。キャラクターを撮影するプロジェクトが作れます。
※キー設定が被ってるのでよしなに。
