二つのカメラをクロスフェードして切り替えます。
概要
やり方はなんてことは無い、ImageEffectとRenderTextureの合わせ技です。もう一つのカメラの描画結果をRenderTextureへ転送しておき、ImageEffectにてクロスフェードしてやれば、上のような結果になります。
カメラのフェード実装方法
まずは二つのカメラを用意します。この各々のカメラは異なる結果を表示します。
片方のカメラの描画結果をRenderTextureを設定します。RenderTextureはスクリプトで作成しても良いですし、アセットとして作成しても良いです。
あとはImageEffectで二つの描画結果をブレンドしてやればOKです。上手く作れば、途中の色も変な感じにならず綺麗にブレンドされます。
フェードが終わったらRenderTextureを外したり表示していない側のカメラをOFFにするなりして、カメラの切り替えを完了させます。
フェード実装時の注意点
絵が上下反転する
なおWindows(のDirectX)で行う場合、QualitySettingsのアンチエイリアスはOFFにします。でないと、RenderTextureが撮影した画面が上下反転します。
またRenderTextureを使用する場合Clear Colorが非常に重要です。ここにアルファがかかっている場合、背景がクリアされず抜ける事があります。
ちゃんとシェーダーで設定すれば回避できる項目ですが、ハマりました。
ScreenOverlayで代用
やり方が良くわからない場合、代替手段として標準提供されているImageEffectのScreenOverlayで似たような事が出来ます。
BlendModeをAlphaBlend、Textureをサブカメラが映したRenderTextureに設定します。Textureは初期状態だとTexture2Dしか設定出来ないので、ScreenOverlayのコード22行目をTexture2DからTextureへ変更して登録可能にします。
あとはIntensityが1に近づけばサブカメラ、0に近づけばメインカメラが撮影した画面にブレンドされます。
uGUIとの連携
uGUIも一緒に出したい場合、2点注意すべき事があります。
まず一つ目はCanvasがScreenSpace-Overlayの場合はImageEffectが機能しない事です。SS-Oはカメラより後に描画されるため、描画結果を使用し変更をかけるImageEffectでは操作する事が出来ません。
なので、ScreenSpace-CameraやWorldSpaceのようなCanvasモードへ変更し、カメラに映してUIを表示する形に変更する必要があります。
もう一つは、RenderTextureをカメラに設定している場合、RenderTextureのサイズがカメラの描画範囲に影響を与える事です。
例えばGameViewが1:1であっても、RenderTextureが4:3の場合RenderTextureのサイズが優先された結果、UIが画面が居へ出てしまうといったケースも考えられます。
なので画面とRenderTextureは、最低でも画面比率は一致させるのが望ましいです。