今回は、何らかの衝撃があったときにカメラを振動させる方法についてです。
カメラの振動
何か衝撃があったとき、カメラを揺らすのはよくある手法です。
ダメージを受けた事を強調したり、クリティカルなダメージを与えたり、巨大な何かが動いた時の迫力を足したりと、様々なケースで使用されます。
今回はその「カメラの振動」をやってみます。
CinemachineのImpulseを使う
今回はCinemachineのImpulse Listenerを使用します。
流れとしては、任意のImpulse Sourceが振動を発信し、Impulse Listenerが受信すればカメラが揺れるという感じです。
当然Cinemachineの利用が前提となります。
まず受信側の設定です。
Virtual CameraのAdd ExtensionsからCinemachineImpulse Listenerを選択します。
これで上のようなコンポーネントが追加されます。
項目がない場合はCinemachineのバージョンが古いかもしれません。この機能は2.2からです。
後は「衝撃」を発行するだけですが、幾つかアプローチがあります。
衝撃を発行する(コライダー編)
まずはColliderから衝撃を発行するCinemachine Collision Impulse Source を見てみます。
この設定では、コライダーが「カメラの近く」で「勢いよくぶつかったら」カメラが振動します。距離による減衰や、質量・加速度の有無等でカメラの衝撃が強弱します。
まずRigidbodyで動くようなオブジェクトに、Cinemachine Collision Impulse Sourceコンポーネントをセットします。
次にSingle Shapeを6D Shakeにセットします。
最後にHow To Generate The Impulseの項目で、全てにチェックを入れます。(振動が向きの影響を受けるか・質量の影響を受けるか・速度の影響を受けるか)
これでCinemachine Collision Impulse Sourceを持つRigidbodyが衝撃を受ければ、衝撃を通知してカメラが振動するようになります。
衝撃を発行する(コード)
コードで衝撃を発行する場合は単純です。
まず適当なオブジェクト(多分マネージャー的な)にCinemachine Impulse Sourceを追加します。Cignal Shapeは6DShakeです。
あとはCinemachineImpulseSourceコンポーネントのGenerateImpulseAtを呼べば良いです。これで画面が振動します。
なおGenerateImpulseでも生成が可能ですがvelocityの値はVector3.down(0, -1, 0)と非常に小さいので、Gainを上げておく等をしないと揺れてないと勘違いします。
Timelineから振動を呼ぶ
Timelineからカメラを振動させてみます。
TimelineにはUnity 2018.2現在「イベント」が無いので、UnityTimelineEventを使用します。
まず、振動を発したいオブジェクトにCinemachine Impulse Sourceを追加します。例えば巨大ロボの足とか、Timelineで動かすならTimelineの子オブジェクトを用意して動かすのが何かと楽で良いです。
あとはTimelineEventからCinemachine Inpulse Sourece.GenerateImpulseを呼び出します。
なお、この時Invoke In Editor Modeにチェックを入れておけばゲームを再生せずとも振動の動きを確認することが出来ます。
Cinemachineの振動はカメラを動かしますが、座標の元となるVirtual Cameraは動いていないので特に問題はないです。
感想
カメラ揺らし、ココゾって所で揺らせば迫力満点です。
もちろん常に揺らすような事をすると飽きるので、そのあたりは使い所を考えると良さそうです。
あとVRでカメラ揺らしは絶対にしない。やったやつ体育館裏な*1
関連
*1:ほんのチョビっとならOKという意見も