プレイヤーの見ている画面とは別視点からのリプレイ動画をお手軽に作れないか頑張った話【Unity Advent Calendar 2017】
この記事はUnity Advent Calendar 2017 2日目の記事です。
ゲームを作っていると、ハイライトやリプレイをリザルトで出したいなーと思うことが常々あるかと思います。
最近だとPS4やNintendo Switchでプレーの録画をSNSにアップロードできたりしますよね。
UnityだとEveryplay SDKで録画機能を実装できます。
ただ、上記の録画機能はプレイヤーの見ている画面を録画していますが、
プレイヤーの見ている画面とは別視点からのリプレイ動画を作れないかな
と思い、今回いろいろ試してみました。
イメージはこんな感じ(ちょっと違うかな?)
作り方
簡単に言うと
- ① カメラを2台用意する
- プレイヤーの見る画面を描画するカメラ
- リプレイの録画に使うカメラ
- ② 録画用のカメラにRenderTextureを設定する
- ③ RenderTextureの描画結果を動画ファイルに書き込む
という感じです。
(プレイヤー画面用のカメラと録画用のカメラの図)
①と②はUnityですぐにできますが、③が考えどころです。
今回はOpenCV for UnityのVideoWriterという機能を使って動画ファイルを生成したいと思います。
実装
実装の細かい話
- Unity Editor(Mac)と、iOSで動作を確認
- 上述した③ RenderTextureの描画結果を動画ファイルに書き込むは
OpenCVForUnity.Utils.textureToMat(Texture texture, Mat mat)
とOpenCVForUnity.VideoWriter.write(Mat image)
で実現したOpenCVForUnity.Utils.textureToMat
で録画カメラのRenderTexture
をMat
に変換。- ただ、
textureToMat(Texture texture, Mat mat)
がiOSでしか動作しない(([作者も確認済みとのこと] (https://forum.unity.com/threads/released-opencv-for-unity.277080/page-28#post-3261290)))ので、他の環境ではRenderTexture
を一旦Texture2D
に変換した上でMat
に変換している RenderTexture
をTexture2D
に変換する場合は内部でTexture2D.ReadPixels
を呼んでいるので処理に時間を要する
OpenCVForUnity.VideoWriter.write
で動画ファイルに書き込み- Androidも動画の拡張子とfourccの選択次第では動きそう(拡張子を
.avi
、fourccを`'M', 'J', 'P', 'G' (Motion JPEG)にしたら録画はできた。しかしVideoPlayerが再生に対応していなかったので今回のサンプルコードから外した) - iPhone SEで↑の動画と同じアプリを動かしたが処理落ちはそこまでなかった。解像度によっては処理落ちを招くケースがありそうなので、その辺は要調整
VideoWriter.write
を呼んでいるところは別スレッドに逃してもいいかも- iPad mini(4th gen)だと30FPSが15FPSまで下がった。おそらくだが
RenderTexture
の解像度を下げれば改善すると思う
- OpenCVのモバイル用のプラグインが結構なサイズ(.frameworkとかだと500MB超えてたり)なので、ビルド時に不要な機能を消したりする必要はありそう
おわりに
今回はOpenCVForUnity(OpenCV)を使って動画の生成を実装しました。
改善すべきポイントは諸々ありますが、手早く作れるのが良いかなと。
ゲーム側でリプレイ機能を自前で作るとなると、設計時点でしっかりやる必要がありますしね😃
やはり理想を言うならネイティブプラグインでしっかり作るのがベストですね。