Unity (Windows) でウィンドウをキャプチャするライブラリを作りました
Unity Windowsでウィンドウをキャプチャできるライブラリ「UnityGraphicsCapture」をつくりました。
Unityでウィンドウやデスクトップ画面をキャプチャする方法といえばhecomiさんのuWindowCaptureが有名ですね。
今回使用したのはWindows 10 1803以降で使用できるWindows.Graphics.CaptureというAPIで、こちらは任意のウィンドウやモニターをDirectXのテクスチャとして取得することができるものです。テクスチャのポインタをそのままUnityで読み込んでTexture2Dとして使用できるためコピーやCPUへの読み戻しの実装が不要で、おそらく低オーバーヘッド、低遅延低負荷で動作します(API側の内部実装がわからないので一概には言えませんが……)。
ついでにキャプチャされているウィンドウに黄色い枠が表示される仕様になっており、ユーザーにとって安心感もあります。
ダウンロード/インストール
UnityGraphicsCapture は Unity Package Manager 形式で配布しています。
1. UnityでPackage Managerを開く
2. 「+」ボタンから「Add package from git URL...」を開く
使い方
一番簡単なのは「CaptureTexture」コンポーネントを使う方法です。
CaptureTextureの使用法
1. 適当なRendererをもつGameObject (QuadやPlaneなど)を配置し、「CaptureTexture」コンポーネントをとりつけます。
2. Playします。
3. CaptureTextureのインスペクタから「...」ボタンを押してウィンドウやモニターを選択します。
4. 対象のレンダラーでウィンドウが表示されます。
スクリプトからウィンドウを設定する
Ruccho.UnityGraphicsCapture.Utilsクラスに、キャプチャターゲットを列挙するメソッドが用意されています。Utils.GetTargets()でキャプチャ可能なすべてのウィンドウ/モニターを取得し、それをCaptureTexture.SetTarget(ICaptureTarget target)で設定することができます。
詳しいサンプルコードはGitHubのREADMEやUnityプロジェクト内にありますので、そちらをご覧ください。
余談
Windows.Graphics.CaptureはC#から直接使用可能なAPIも存在するのですが、こちらはWinRTのAPIなのでUWP限定です。そこでUnityGraphicsCaptureではC++/WinRTのネイティブプラグインを経由してテクスチャを取得しており、こうすることでWindows Standalone ビルドでも動作させることができます。(C++をまともに扱った経験がないので実装にはあまり自信がありませんが……)