Unity モバイル端末でUI無しのAR画面だけのスクリーンショットを撮影する方法


# 概要
ARアプリを作成した際に、共有用にスクリーンショットを撮りたい場面があるかと思います。

画面そのままならスマホ側のスクショ機能を用いれば良いですが、UIを取り除いたARシーンだけ撮影したい場合、Unity側で実装をする必要があります。
本記事ではカメラロールに保存するためのパッケージであるNativeGalleryパッケージを用いた実装を解説します。

サンプルプロジェクトのソースコードはこちら
https://github.com/Arihide/unity-mobile-ar-screenshot

# 解説
サンプルの作成の流れを説明します。
ビルドが大変なため、Androidに絞って解説しますが、iOSでも同様にビルドすれば動作します。

## AR・UIシーン作成
まずスクショ確認用のプロジェクトを作成します。

今回はUnity側に準備されているARテンプレートを使用します。
![スクリーンショット 2023-07-20 17.56.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/42f5c8fb-3526-e34b-f3fa-b08dfcf95fcb.png)

サンプルシーンを開きます
![スクリーンショット 2023-07-26 19.54.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/23296c66-ee40-6770-e6b2-3498a5ffb860.png)

SampleSceneにCubeObjectプレハブを配置します。
![スクリーンショット 2023-07-30 14.57.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/792d9798-c8c5-e562-0ee6-df133046acf0.png)


続いて、UI描画用のカメラとキャンバス・スクショ用ボタンを用意します。
![スクリーンショット 2023-07-30 15.11.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/0ef042ed-4f34-9149-bcdf-09898129a0e7.png)


:::note info
今回はUIのRender ModeをScreen Space - Overlayで描画していますが、この場合後述するRenderTextureを用いたスクショ撮影にはUIが乗らない性質があるため今回はそれを利用します。

Screen Space - Cameraの場合は、別でUI用カメラを用意した上で、Culling Modeを分けることで適切に描画範囲を設定してください。
:::

以上でシーンの設定は完了です

## スクショ撮影機能実装
続いてシーン撮影用のスクリプトを記述します。

### NativeGallery導入
まず撮影したスクショをカメラロールに保存するためのパッケージである、**NativeGallery**をプロジェクトに追加します。

追加方法はmanifest.jsonに以下の1行を足すだけで良いです。
```json:manifest.json
"com.yasirkula.nativegallery": "https://github.com/yasirkula/UnityNativeGallery.git",
```
パッケージの詳細はGithubページを参照ください。
https://github.com/yasirkula/UnityNativeGallery


### スクリプト記述
本命であるスクショ撮影スクリプトを以下のように記述します。
処理の内容についてはコメントを参照ください。
```c#:ScreenCapture
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScreenCapture : MonoBehaviour
{
    [SerializeField] private Camera _captureCamera;

    public void TakeScreenshot()
    {
        // スクショ用の、ARカメラ描画結果を格納するRenderTextureを用意する
        RenderTexture rt = RenderTexture.GetTemporary(Screen.width, Screen.height, 24, RenderTextureFormat.ARGB32);

        // 用意したRenderTextureに書き込む
        RenderTexture prevTarget = _captureCamera.targetTexture;
        _captureCamera.targetTexture = rt;
        _captureCamera.Render();
        _captureCamera.targetTexture = prevTarget;

        // RenderTextureのままでは保存できないので、Textureに変換する
        RenderTexture prevActive = RenderTexture.active;
        RenderTexture.active = rt;
        Texture2D screenShot = new Texture2D(_captureCamera.pixelWidth, _captureCamera.pixelHeight, TextureFormat.ARGB32, false);
        screenShot.ReadPixels(new Rect(0, 0, screenShot.width, screenShot.height), 0, 0, false);

        try
        {
            string timestamp = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss");

            NativeGallery.Permission permission = NativeGallery.SaveImageToGallery(screenShot, "ShreenshotSample", $"screenshot_{timestamp}.jpg", (success, path) =>
            {
                // 保存終了時のコールバック
            });
        }
        catch (IOException e)
        {
            // 保存時エラーが出た時の処理を記述
        }
        finally
        {
            // 最後にARカメラの描画先をスクリーンに戻す
            RenderTexture.ReleaseTemporary(rt);
            RenderTexture.active = prevActive;
        }
    }
}
```

撮影したコンポーネントをAR カメラにアタッチします
![スクリーンショット 2023-07-26 20.27.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/b04063d4-fab4-731c-ec36-7ee35070b4ce.png)

Canvasに追加したButtonコンポーネントのイベントにスクショを追加します
![スクリーンショット 2023-07-26 20.33.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/f1a0ba69-bf21-d49a-7f9e-64d37a56fa83.png)


これでスクリプトの準備もできました。
## ビルド

最後にサンプルプロジェクトをビルドして実機確認しましょう！

まずProjectSettingsのARCoreが有効になっていることを確認します
![スクリーンショット 2023-07-26 20.24.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/26b47313-d280-9b46-355c-bde20561fed7.png)

続いてBuild Settingsに移動し、SampleSceneを追加した上でAndroid端末をPCに接続します。
そしてBuild And Runを実行
![スクリーンショット 2023-07-26 20.29.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/55dd5b17-f76b-a498-b78c-545b48df4880.png)

ボタンを押下してUIなし画像が撮れていれば成功です！

![Screenshot_20230727-155949（大）.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/ca89b370-3480-ad29-7b16-3479f5389592.jpeg)
![screenshot_2023_07_27_15_59_52（大）.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/7794b15a-807b-05fb-e45d-d61705293076.jpeg)