UnityでUIを消したスクリーンショットを撮る方法

  • 9
    いいね
  • 0
    コメント

Application.CaptureScreenshotで基本的にはキャプチャを撮る事が出来るけど、
これ当然ながら画面のUIが写った状態でしかキャプチャ出来ない……
これだとキャプチャボタンを使って撮影させる場合になんともダサい画像になってしまう。
test.png

それを解消する方法とスクリプトを作成してみた。

①UIのオブジェクトを非表示にしてキャプチャ終わったら再表示

最初にぱっと思いついた方法。
一件楽そうだが、この方法だと押したタイミングでユーザの表示から消える上、
キャプチャが終了した事をファイルチェックなりで確かめないといけないと考えて、
実装前にやめた。

②Camera→RenderTexture→Texture2D→PNGにする

これが今回実装した方法。
CanvasのRender Modeが「Screen Space - Overlay」の場合、
「UIを写すカメラとGameのカメラが異なる」という性質を利用し、
Cameraの映像を一旦RenderTextureに変換
→RenderTextureをTexture2Dに変換
→Texture2DをPNGに変換
→ファイルに流し込む
→邪魔なオブジェクトを消す
という方法。

以下のサイト等を参考にしながらスクリプトを作成した。
https://docs.unity3d.com/ScriptReference/Texture2D.EncodeToPNG.html
http://blog.livedoor.jp/ituki_yu/archives/27225941.html

ScreenShot.cs

using System.Collections;
using System.IO;
using System;
using UnityEngine.UI;
using UnityEngine;

public class ScreenShot : MonoBehaviour {
    public Camera ArCam;

    public void CaptchaScreen()
    {
        Texture2D screenShot = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
        RenderTexture rt = new RenderTexture(screenShot.width, screenShot.height, 24);
        RenderTexture prev = ArCam.targetTexture;
        ArCam.targetTexture = rt;
        ArCam.Render();
        ArCam.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);

        string fileName = "cap_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".png";

        File.WriteAllBytes(Application.persistentDataPath + "/" + fileName, bytes);
    }
}

これをボタンと連携すれば、こんな感じのキャプチャが撮れる。
stamp5-iloveimg-compressed.gif
↓結果
fure_20170419195926756.png

※キャプチャの内容は気にしないで頂ければと思います。

まとめ

一旦この方法でUIを排除したキャプチャを作ることは出来る。
ただスマフォだと一瞬動作が止まる。シャッターっぽい動きを加えたら動作ストップも気にならないかも。
もっとスマートな方法があるかもしれない……?