ギャグ調の漫画やアニメで、一つのカットを別視点で何回も繰り返すっていう手法があると思うんですけど、あれがやりたかっただけ。
・どう実現するか
二つ方法が思いついて
- オブジェクトの状態をある地点まで戻して再度動かす
- 繰り返したいカットだけ動画として保存しておく
1は正直いろいろ処理が面倒ですよね。
位置だけでなく、物理挙動をしていたらその状態まで保存しなきゃならないし、アニメーションの件もある。
(まあストアにちょうどいいアセットがあるんだろうけど)
なので今回は2の方法で実現してみました。
カメラを配置して出力先をRenderTextureにする
まずメインのゲームカメラの他に、撮影したいアングルのカメラを設置します。
そして、このカメラの映像を受け取るためのRenderTextureをアセットとして作成。
プロジェクトを右クリックし、Create > RenderTexture から作成です。
そして、各カメラのTargetTextureに作成したRenderTextureを設定しておきます。
これでカメラの映像はスクリーンには表示されず、RenderTextureに画像として出力されます。
RenderTextureの画像をpngとして出力
下のようなかんじのスクリプトでRenderTextureの画像をファイルとして出力します。
void RenderTextureImg(string filePath) { // RenderTextureに描画されたカメラの画像を // テクスチャとして取得 var oriRenderTexture = RenderTexture.active; RenderTexture.active = renderTexture; tex.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); tex.Apply(); // ファイルに書き出す byte[] bytes = tex.EncodeToPNG(); File.WriteAllBytes(filePath, bytes); // 後処理 RenderTexture.active = oriRenderTexture; }
本当は RenderTexture.GetTemporary で一時領域を使いたかったんですけど、二つ以上のカメラを使ったときにどうしても同じアングルになってしまうのであきらめました。
出力した画像をコマ送りアニメとして表示
再生したいタイミングでpngを読み込み、RawImageにコマアニメとして表示します。 下の過去記事参照。
たぶんモバイルだとファイル書き出しの処理が重くて、フレームレートの維持が難しいと思います。
PCだったら十分実用レベルかもしれません。