UIなどにプレイ中の画面を載せるために画面をキャプチャしたかったのですが、
「自分でRendererFeature作ってキャプチャ用のPass作って…」としようとした所、
もっと簡単にキャプチャすることが出来たので記事にしておきます。
- Unity2021.2.1f1
- UniversalRP 12.1
キャプチャ用クラスを作る
何と、面倒な手続きを踏まなくても、こちらのクラスが有ればキャプチャできます
using UnityEngine;
using UnityEngine.Rendering;
namespace ScreenPocket
{
/// <summary>
/// カメラの描画後のキャプチャを取る
/// カメラがスタックされている場合スタックの最後まで描画された後でキャプチャする
/// </summary>
public sealed class CaptureObject : MonoBehaviour
{
/// <summary>
/// キャプチャしたいBaseカメラ
/// </summary>
[SerializeField]
private Camera _target;
/// <summary>
/// キャプチャ用RenderTexture
/// </summary>
private RenderTexture _captureBuffer;
private void Start()
{
//↓サイズ、名前などは自由に設定しましょう
_captureBuffer = new RenderTexture(256, 512, 0, RenderTextureFormat.Default);
_captureBuffer.name = "_CaptureBuffer";
//キャプチャ用Action登録
CameraCaptureBridge.AddCaptureAction(_target, Capture);
}
private void Capture( RenderTargetIdentifier ri, CommandBuffer cmd )
{
cmd.Blit(ri, _captureBuffer);
}
private void OnDestroy()
{
//キャプチャ用Action片付け
CameraCaptureBridge.RemoveCaptureAction(_target, Capture);
}
}
}
という事で以上です。
#今回の記事のポイント
「思ったより簡単じゃないじゃないか」とお𠮟りを受けそうですが、
今回の記事で一番のポイントが
CameraCaptureBridge.AddCaptureAction(_target, Capture);
を使えば、 UniversalRP標準のUniversalRendererのCapturePassが作動する という事なのです。
つまり、自分で他にキャプチャ用のRenderTextureを管理している&キャプチャしたいカメラを握っている場合は、
- CameraCaptureBridge.AddCaptureAction()
- キャプチャ用関数(上記クラスで言うCapture())
- 用が済んだ時のCameraCaptureBridge.RemoveCaptureAction()
さえあればキャプチャが可能となるわけです。**最少、3行追加するだけ!**なので簡単!
#注意点
UniversalRPのCapturePassのRenderPassEventがRenderPassEvent.AfterRenderingとなっている都合上、
スタックされたカメラの描画が全て終わった後でキャプチャしてしまう点だけご注意ですね。
つまり 「UIカメラをスタックしている時に、UIだけはキャプチャ対象外にしたい!」 という場合などは、
やはり自分でオレオレCapturePassを準備してRenderPassEventを調整できるようにした方が良さそうです
にしてもこんな使いやすい仕組み(CameraCaptureBridge)が何処からも参照されていない事が不思議ですが、
もしかするとUnityRecorderなどで使用されているのかもしれませんね(未確認)