ブループリントからスクリーンショット撮影する

UnrealEngineでブループリントからスクリーンショットの撮り方について、調査してみた為、メモを書いて行こうと思います。


# 確認環境
UnrealEngine 4.26.2


# スクリーンショットを撮る方法

スクリーンショット撮影する方法は、実に様々です。
エディタから撮影を行う場合は、[ヒストリアさんのブログ](https://historia.co.jp/archives/12248/)でも紹介されています。
また、C++からスクリーンショット撮影も、同じく[ヒストリアさんのブログ](https://historia.co.jp/archives/5917/)で紹介されています。

コンソールコマンドとして、スクリーンショット撮影可能なコマンドは、「HighResShot」「Shot」といったものが存在します。
この記事では、用途として条件を揃っていた、コマンドの「HighResShot」を使った撮影を紹介しています。


# HighResShotを使う利点

個人的にHighResShotを使った利点です。

1. C++等の実装が必要ない為、簡単に試せる
2. 出力先を指定可能
3. 出力サイズを指定可能
4. 出力領域を指定可能
5. ファイル名にタイムスタンプや自動で連番を付与してくれる


# スクリーンショットを撮る(基本操作)

基本的な方法は、[公式のドキュメント](https://docs.unrealengine.com/4.26/ja/WorkingWithMedia/TakingScreenshots/)に記載があります。
スクリーンショットで撮影される画像は、pngで書き出されます。

下記のコマンドで、スクリーン解像度の2倍の大きさでスクリーンショットを撮影できます。

```biml
HighResShot 2
```

下記の操作コマンドで、幅1600 、高さ1200 のサイズのスクリーンショットを撮影できます。

```biml
HighResShot 1600x1200
```

注意点として、引数には、最低限、「XxY」か「Multiplier」でサイズの指定する必要があります。
サイズの指定がない場合は、以下の警告がアウトプットログに流れます。

```biml
Error: Bad input. Input should be in either the form "HighResShot 1920x1080" or "HighResShot 2"
```

また、ExecuteConsoleCommandノードを使えば、ブループリントからも実行する事が可能で、今回は、ExecuteConsoleCommandノードを使って検証しています。
ブループリントから実行する際は、エディタモード(非プレイ時)である必要があり、ビューポートの画面をスクリーンショットで撮影します。

![ExecuteConsoleCommand.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/d367a642-5a75-bc09-6395-d3b2b58520bb.png)


# スクリーンショットを撮る(オプション)

HighResShotコマンドには、いくつかのオプションがあり、そのオプションの使い方について、検証したため、説明していきたいと思います。
[公式のドキュメント](https://docs.unrealengine.com/4.26/ja/WorkingWithMedia/TakingScreenshots/)に、設定可能なパラメータの一覧が存在します。

 * filename

出力先とファイル名を設定可能です。この引数が空の場合は、Savedフォルダの中に保存されます。

```biml
プロジェクトのルートフォルダ\Saved\Screenshots\Windows
```

__コマンド例__

```biml
HighResShot filename="D:/test.png" 1600x1200
```

他にも注意点があります。

1. filenameに渡すパスは、<font color="red">__スラッシュを使用__</font>してください。「\\(バックスラッシュ)」だと、動作しない為、エクスプローラーのパスをコピーして貼り付ける際は、注意してください。
2. 「"(ダブルクォーテーション)」は、必須ではりませんが、付けておいた方が安全です。
3. サイズ指定は必須なので省略できません。
4. 「/(スラッシュ)」で終わるようなフォルダのパスだけ指定した渡し方をすると、無名のpngファイルを作成されてしまいます。
5. 以下の警告が出て、Cドライブの直下には、出力は行えません。

```biml
LogImageWriteQueue: Error: Failed to write image to 'C:/test.png'. The pixel format may not be compatible with this image type, or there was an error writing to that filename.
```


 * CaptureX CaptureY CaptureW CaptureH

出力領域を指定可能です。全て0だと、ビューポートのサイズで書き出します。

__コマンド例__

```biml
HighResShot filename="D:/test.png" 1600x1200 500 500 700 700
```

書き出した結果を比べてみると、画像の一部を切り取って、出力されている事が分かるかと思います。

![説明.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/01991b04-67d8-8f27-0f5f-ac5e2f8d9ff6.png)



 * bMaskUsingCustomDepth

このフラグが1の場合は、CustomDepthStencilValueが0以外のオブジェクトを書き出します。

__コマンド例__

```biml
HighResShot filename="D:/test.png" 1600x1200 0 0 0 0 1
```

下の画像の場合は、白いスフィアとボックスのみ、CustomDepthStencilValueを0以外の数字を入れています。
その為、右の画像では、スフィアとボックスのみしかレンダリングされていません。画像だと、背景が白で塗りつぶされているように見えますが、実際には色が抜けています。

![bMaskUsingCustomDepth説明.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/ca103521-decf-76de-c1e0-5fc017586387.png)


 * bDumpBufferVisualizationTargets

このフラグを立てて、スクリーンショット撮影すると各GBufferのパスまとめて出力されます。
![DumpBufferVisualizationTargetsの説明.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/7bb604c7-59ea-240a-349b-c2d009b7c60c.png)

__コマンド例__

```biml
HighResShot filename="D:/test.png" 1600x1200 0 0 0 0 0 1
```


 * bCaptureHDR

bCaptureHDRは、bDumpBufferVisualizationTargetsが1以外の場合は、無視されます。
bCaptureHDRを1にすると、bDumpBufferVisualizationTargetsで出力したものが、OpenEXR形式で出力されます。

![CaptureHDRの説明.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/c0cd2a3c-18f1-90c6-9e17-b50ffacb63aa.png)

__コマンド例__

```biml
HighResShot filename="D:/test.png" 1600x1200 0 0 0 0 0 1 1
```

 * bDateTimeAsFilename
 
 この引数は、filenameが空でないと動作しません。理由は、以下の画像の実装のようになっている為です。

![UnrealClientのfilenameのチェック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/df7eb217-a870-3d34-dc54-f0457446be69.png)

__コマンド例__

```biml
HighResShot filename="" 2166x1246 0 0 0 0 0 0 0 1
```


実行した結果は、以下の通りです。右が通常のファイル名となり、左がタイムスタンプを付けた場合のファイル名となります。
このオプションを使用する場合は、出力先を変更できません。

![DataTimeAsFilename_Result_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/81f0e969-23e5-addd-2140-37bdb0076227.png)



# スクリーンショットを撮る(その他)

 * アイコンを非表示にする

エディタモードで、スクリーンショットを撮影した場合に、そのままの状態ではライトやデカールなどのアイコンが表示された状態で、撮影されてしまいます。
[EditorSetGameView](https://docs.unrealengine.com/4.26/en-US/BlueprintAPI/EditorScripting/LevelUtility/EditorSetGameView/)を実行してから、HighResShotコマンドを実行する事で、アイコンを非表示にした状態で、スクリーンショットを撮影できます。

![アイコン非表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/87998545-1086-2c2f-e6aa-0b761b29db71.png)



 * HighResShot は、実際に撮影していない

HighResShotコマンドは、スクリーンショット撮影する処理を実際に行っている訳ではなく、スクリーンショット撮影の際に、参照されるパラメータに引数を渡しているだけです。
実際に、スクリーンショットの撮影は、FViewport::Drawで実行されています。
つまり、HighResShotを実行し、すぐにスクリーンショット撮影が行われる分けではなく、<font color="red">__若干のタイムラグが発生する__</font>事に注意してください。
また、新しく引数が設定されなければ、スクリーンショットの撮影時に参照されるパラメータも前回、スクリーンショットの撮影に使用したパラメータが、<font color="red">__そのまま維持されて使用される事__</font>にも注意してください。