概要
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】カメラ移動を制御するスクリプト
上記を参考にしてみてください。キャラクターを撮影するプロジェクトが作れます。
※キー設定が被ってるのでよしなに。