Cinemachineを使って、一人称カメラとフリールックカメラを簡単に切り替えてみました。また巨人が歩く衝撃に合わせてカメラを揺らします。
Starter Assets
今回は、無料の「Starter Assets – First Person Character Controller | URP」を使いました。
https://assetstore.unity.com/packages/essentials/starter-assets-first-person-character-controller-urp-196525Playgroundシーンでは、プレイヤーにカメラのルートを表す空のゲームオブジェクトがあります。一人称視点用のバーチャルカメラはこのゲームオブジェクトを親にせず、インスペクタでFollowに設定しています。
バーチャルカメラのBodyプロパティは「3rd Person Follow」で、減衰や位置、距離などの値が0です。
TPSでも同じBodyプロパティが使われています。フィールドの値を0にすると一人称カメラに変わります。
また、Noiseプロパティでパーリンノイズが選択されていて、画面が常に揺れています。
Free Look Camera
ヒエラルキービューでCinemachine > FreeLook Cameraを追加します。
FreeLook Cameraは、マウス等の入力によってカメラがターゲットの周囲の軌道を回ります。デフォルトでは横方向に動かすとカメラがターゲットの周囲を周り、縦方向ではカメラの高さが変わります。
キャラクターの頭のゲームオブジェクトをFreeLook CameraのFollowとLookAtにアタッチします。
これで、FreeLook Cameraがキャラクターの周囲の軌道を周りながら、キャラクターの方を向き続けます。
軌道は3つのリグで指定します。これらはシーンビューでターゲットを囲う赤い円で表示されます。
インスペクアで各リグの高さや半径を変更できます。
リグごとに別のLookAtターゲットをオーバーライドできます。一番下のリグではバーチャルカメラが足元を向くようにしました。
Save During Playをオンにすると、プレイモードでの変更が保存されます。
バーチャルカメラを切り替える
Cinemachine Brainは、Priorityの値によってライブにするバーチャルカメラを選択します。フリールックカメラもバーチャルカメラと同様に扱われます。
バーチャルカメラを切り替えるには、スクリプトでPriorityの値を変更したり、残りのバーチャルカメラを無効化します。
スクリプト
using UnityEngine;
using Cinemachine;
public class TestVCameraSwitcher : MonoBehaviour
{
[SerializeField] CinemachineVirtualCameraBase FPSCamera;
[SerializeField] CinemachineVirtualCameraBase FreelookCamera;
//bool freelook;
private void Start()
{
FPSCamera.gameObject.SetActive(true);
FreelookCamera.gameObject.SetActive(false);
// FreelookCamera.Priority = 9;
//FPSCamera.Priority = 10;
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
FreelookCamera.gameObject.SetActive(FPSCamera.gameObject.activeSelf);
FPSCamera.gameObject.SetActive(!FreelookCamera.gameObject.activeSelf);
/*
freelook = !freelook;
if (freelook)
{
FreelookCamera.Priority = 11;
FPSCamera.Priority = 10;
}
else
{
FreelookCamera.Priority = 9;
FPSCamera.Priority = 10;
}
*/
}
}
}
バーチャルカメラやフリールックカメラの基底クラスのCinemachineVirtualCameraBaseクラスのフィールドを定義しているので、どちらのカメラもアタッチできます。
using UnityEngine;
using Cinemachine;
public class TestVCameraSwitcher : MonoBehaviour
{
[SerializeField] CinemachineVirtualCameraBase FPSCamera;
[SerializeField] CinemachineVirtualCameraBase FreelookCamera;
//bool freelook;
片方だけをアクティブにしたり、Priorityを変更することで切り替えられます。
void Update()
{
if (Input.GetMouseButtonDown(0))
{
FreelookCamera.gameObject.SetActive(FPSCamera.gameObject.activeSelf);
FPSCamera.gameObject.SetActive(!FreelookCamera.gameObject.activeSelf);
/*
freelook = !freelook;
if (freelook)
{
FreelookCamera.Priority = 11;
FPSCamera.Priority = 10;
}
else
{
FreelookCamera.Priority = 9;
FPSCamera.Priority = 10;
}
*/
}
}
バーチャルカメラ間のブレンド
切り替える際バーチャルカメラ間をなめらかにブレンドできます。CinemachineBrainコンポーネントで、ブレンドのスタイルや時間を設定します。
Custom Blendsのリストで、特定のバーチャルカメラ間のブレンドを設定できます。
リストで定義されていないものは、Default Blendが使われます。
インパルスソース
巨人が足を踏み鳴らしたときにバーチャルカメラを揺らします。巨人の足のゲームオブジェクトにCinemachine Impulse Sourceコンポーネントを付けます。
Impulse Typeを「Propagating」にすると、遠くのインパルスが弱く遅くなります。Impulse Shapeで、インパルスの形状と持続時間を指定できます。
インパルスの生成
CinemachineImpulseSource.GenerateImpulseメソッドでインパルスを生成します。
using UnityEngine;
using Cinemachine;
[RequireComponent(typeof(CinemachineImpulseSource))]
[RequireComponent(typeof(AudioSource))]
public class GiantFoot : MonoBehaviour
{
[SerializeField] FootstepSmokeVFXController vfxController;
AudioSource audioSource;
CinemachineImpulseSource impulseSource;
private void Start()
{
audioSource = GetComponent<AudioSource>();
impulseSource = GetComponent<CinemachineImpulseSource>();
}
public void Stomp()
{
// 足音を再生
audioSource.Play();
// インパルスを生成
impulseSource.GenerateImpulse();
// エフェクトを再生
vfxController.PlayVFX(transform.position);
}
}
GenerateImpulseAtメソッドの場合、引数に位置と速度を渡せます。足の着地する位置を渡してCinemachineImpulseSourceコンポーネントを一つにできます。
// ...
[SerializeField] CinemachineImpulseSource impulseSource;
// ...
public void Stomp()
{
// ...
impulseSource.GenerateImpulseAt(transform.position, -Vector3.up);
// ...
}
}
巨人の歩くアニメーションのインポート設定でイベントを設定して、巨人のスクリプトを実行しています。
using UnityEngine;
using UnityEngine.AI;
public class TestGiant1 : MonoBehaviour
{
// ...
[SerializeField] GiantFoot leftFoot;
[SerializeField] GiantFoot rightFoot;
// ...
void LeftFootStomp()
{
leftFoot.Stomp();
}
void RightFootStomp()
{
rightFoot.Stomp();
}
}
インパルスに反応する
バーチャルカメラにImpulse Listenerコンポーネントをつけると、インパルスでカメラを揺らせます。
バーチャルカメラのAdd Extensionのドロップダウンメニューから「CinemachineImpulseListener」を選択してコンポーネントを追加します。
Gainでインパルス信号を増幅できます。Secondary Noiseを設定すると、インパルスに反応してカメラが揺れ続けます。
バーチャルカメラごとに設定を変えました。