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