2020/11/09
今回はUnityのWebGLで画面キャプチャに関するお話です。
キャプチャした画像をゲーム内で使用したり、外部ストレージにアップロードしたりするケースを想定します。
実装方法
Unityでスクショと言えばScreenCapture.CaptureScreenshot()がありますが、WebGL上ではファイルを扱えません。
そこでTexture2DのReadPixels()を使用します。
https://docs.unity3d.com/ja/2017.4/ScriptReference/Texture2D.ReadPixels.html
注意点として、「OnPostRender()メソッド内」か「コルーチンのWaitForEndOfFrame()の後」で呼び出さないと、以下のようなエラーが発生してしまいます。
ReadPixels was called to read pixels from system frame buffer, while not inside drawing frame.
私はコルーチン内でWaitForEndOfFrame()を待つ方法で実装してみました。メソッド化して任意のタイミングで呼べるようにします。
protected Texture2D currentScreenShotTexture;
protected void Start()
{
    // スクリーンショット用のTexture2D用意
    currentScreenShotTexture = new Texture2D(Screen.width, Screen.height);
    StartCoroutine(UpdateCurrentScreenShot());
}
protected IEnumerator UpdateCurrentScreenShot()
{
    // これがないとReadPixels()でエラーになる
    yield return new WaitForEndOfFrame();
    currentScreenShotTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
    currentScreenShotTexture.Apply();
}
キャプチャ画像はEncodeToPNG()で.png形式のbyte配列に変換できます。
また、base64エンコードすると文字列で取得できるので、HTTPリクエストのJSONに含めて外部のシステムやサービスへ送信できます。
byte[] imageBytes = currentScreenShotTexture.EncodeToPNG(); var encodedImage = Convert.ToBase64String(imageBytes)
受け取った側ではConvert.FromBase64String()でbyte配列に戻し、それをStreamに書き込んで出力すればOKです。
私の場合はAWSのS3にアップロードする用途で使用しました。下はS3にアップロードした画像です。特に問題なさそうですね。
AWSのSDKがWebGLに非対応のため、直接はS3にアップロードできません。Lambdaで一度受けてデコードし、そこからS3に保存する形になるかと思います。
このあたりも最近実装したので、改めて記事でまとめます!
→(2019/11/24)記事書きました!
参考サイト
・画面キャプチャの取得
https://qiita.com/tempura/items/e8f4bbb4419407916d12


 
					 
					 
					 
					 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
						 
                         
                         
                        



