【Unity】Cinemachineでいくつかカメラワークを作ってみる【応用編】

Unity
マイケル
マイケル
みなさんこんにちは!
マイケルです!
エレキベア
エレキベア
クマ〜〜〜
マイケル
マイケル
前回Cinemachineの基本的な使い方について見てみたけど
今回は更に一歩踏み込んだカメラワークをいくつか作ってみようと思います!
エレキベア
エレキベア
どんなカメラワークを作るクマ?
マイケル
マイケル
今回は、今作っているゲームで使おうと思ってる

・Target全体をカメラ全体に収めるカメラワーク
・複数カメラを任意のタイミングで切り替えるカメラワーク
・パス上を移動するカメラを切り替えるカメラワーク

について作ってみようと思うよ!
エレキベア
エレキベア
おお〜〜〜それっぽいクマ〜〜〜
これは楽しみクマね
マイケル
マイケル
なお今回使用するUnityとCinemachineのバージョンは下記になります!
使用するバージョンにより操作が異なる可能性もあるのでご注意ください!
バージョン
Unity2021.3.1f
Cinemachine2.8.6
スポンサーリンク

用意されているカメラの種類

マイケル
マイケル
制作に入る前に、Cinemachineに用意されているカメラの種類について
ざっと見ていきましょう!
マイケル
マイケル
Create -> Cinemachineで一覧を見ると分かる通り、
下記の種類のカメラが用意されています。
ScreenShot 2022 07 31 9 52 04↑カメラの種類
種類概要
FreeLookCameraマウス入力にてカメラを移動、回転できる
BlendListCamera複数のカメラを時間経過で切り替える
StateDrivenCamera複数のカメラをAnimatorのStateに応じて切り替える
ClearShotCamera追従対象が適切に描画されるようカメラを切り替える
DollyCamera with Trackカメラをパスに沿って動かす
CinemachineDollyCartオブジェクトをパスに沿って動かす
CinemachineTargetGroup複数のオブジェクトがカメラに収まるよう移動する
CinemachineMixingCamera複数のカメラを合成する
2D Camera2D表示に特化したカメラ

↑それぞれのカメラの概要

エレキベア
エレキベア
うげ〜〜
こんなに用意されているクマか
マイケル
マイケル
今回はこの中のいくつかを活用しながら作っていきます!
一つ一つについては解説しませんが、そちらに関しては青木ととさんのCinemachine紹介動画がとても分かりやすいのでこちらをご参照ください!!

【復習】10分でCinemachine
↑青木ととさんの動画

エレキベア
エレキベア
むしろCinemachineについてはこの動画だけで十分クマ
ありがたいクマ・・・

Case1. Target全体を画面内に収める

マイケル
マイケル
まずはTargetとなるオブジェクトを常に画面内に収める方法についてです!
下記のように画面サイズを変えても全体に移してくれるので、様々な画面に対応したい場合に重宝しそうです!
01 target group↑画面内に収める
エレキベア
エレキベア
これはよく使えそうクマね
マイケル
マイケル
こちらはTarget Group Cameraを使用すると簡単に作成できます!
Create -> Cinemachine から作成すると、Virtual CameraとTargetGroupのオブジェクトが作成されます。
ScreenShot 2022 08 07 9 58 46
ScreenShot 2022 08 07 13 25 02↑Virtual CameraとTargetGroupのオブジェクトが作成される
マイケル
マイケル
VurturlCameraのFollow、LookAtにTargetGroupが指定されていて、
TargetのオブジェクトはTargetGroupの方で指定する形となります。
ScreenShot 2022 08 07 9 59 51↑TargetGroupが指定されている
エレキベア
エレキベア
TargetGroupのコンポーネントにオブジェクトを設定したら
画面に写るよう調整してくれる
わけクマね
でもこれはオブジェクト1つの場合でも使えるクマ??
マイケル
マイケル
基本的には複数のオブジェクトをグループとして全体を画面に写すのに使用するのですが、
オブジェクト1つでも設定することができるため単純に画面に写したい場合にも使用することができるみたいです!
ScreenShot 2022 08 07 10 03 45↑ターゲットを複数指定した場合
ScreenShot 2022 08 07 10 04 00↑ターゲットが全て画面に映る
ScreenShot 2022 08 07 10 04 22↑ターゲットを1つだけ指定した場合
ScreenShot 2022 08 07 10 04 37↑1つでも画面内に写すよう調整してくれる
マイケル
マイケル
こんな感じですね!
エレキベア
エレキベア
なるほどクマ〜〜〜
これなら画面に写したいだけにも活用できそうクマ

Case2. 複数カメラを任意のタイミングで切り替える

マイケル
マイケル
次は下記のように複数設置してあるVirtual Cameraを切り替える方法についてです!
ScreenShot 2022 08 07 10 23 51↑各オブジェクトに対してVirtualCameraを割り当てている状態
エレキベア
エレキベア
むむ、簡単にできる方法はあるのかクマね〜〜

指定秒数で切り替える場合

02 blend list
マイケル
マイケル
このように指定秒数で切り替えたい場合には簡単で、
BlendListCameraを使用すると実現できます!
ScreenShot 2022 08 07 10 14 03↑BlendListCameraを作成する
マイケル
マイケル
カメラの切り替え処理はBlendListCameraが担う形になり、
指定した順番で切り替えを行うことができます。
下記はそれぞれのカメラを2秒ごとに切り替える例になります。
ScreenShot 2022 08 07 10 24 06↑カメラを切り替える設定例
エレキベア
エレキベア
これはお手軽に使えるクマね〜〜

任意のタイミングで切り替える場合

03 change camera
マイケル
マイケル
しかしこのようにボタン押下時など任意のタイミングで切り替えたい場合には
自前でスクリプトを記述しなければなりません。
どのカメラを優先するかはPriorityの値で決まるため、下記のようにボタン押下時に設定値を変更することで切り替えることができます。
using System.Collections.Generic;
using Cinemachine;
using UnityEngine;
using UnityEngine.UI;

public class ChangeVirtualCameraScript : MonoBehaviour
{
    [SerializeField] private List<CinemachineVirtualCamera> virtualCameras;
    [SerializeField] private List<Button> changeCameraButtons;

    private void Awake()
    {
        // ボタン押下イベントを設定
        for (var i = 0; i < changeCameraButtons.Count; i++)
        {
            var index = i;
            changeCameraButtons[i].onClick.AddListener(() => ChangeVirtualCamera(index));
        }
    }

    /// <summary>
    /// VirtualCameraを切り替える
    /// </summary>
    /// <param name="index">切り替えるCameraのindex</param>
    private void ChangeVirtualCamera(int index)
    {
        // 全てのカメラのPriorityを下げる
        foreach (var virtualCamera in virtualCameras)
        {
            virtualCamera.Priority = -1;
        }
        // 対象のカメラのPriorityを上げる
        virtualCameras[index].Priority = 10;
    }
}
マイケル
マイケル
このスクリプトにカメラとボタンをアタッチすると
切り替え処理の完成です!
ScreenShot 2022 08 07 11 04 09
エレキベア
エレキベア
スクリプトは作らないといけないクマが、
値を一つ変えるだけで済むのは楽クマね

Case3. パス上を動くカメラを切り替える

マイケル
マイケル
最後にパス上を動くカメラを切り替えて簡単なアニメーションを作成
してみようと思います!
エレキベア
エレキベア
タイトル画面とかでよくあるやつクマね
マイケル
マイケル
作成に入る前に、既存で用意されたパスを使用したカメラの
・DollyCamera with Track
・CinemachineDollyCart
の概要について軽く見ていきます!
DollyCamera with Track
マイケル
マイケル
作成時にDollyCamera with Trackを選択すると
DollyTrackというパスと、VirtualCameraが作成されます。

DollyCartにカメラを置くことで動かすことも可能

ScreenShot 2022 08 07 12 25 13↑DollyCamera with Trackを作成
ScreenShot 2022 08 07 12 30 35↑パスとカメラが作成される

マイケル
マイケル
作成されたVirtualCameraの設定をみてみるとTracked Dollyが指定されており、
こちらのPathPositionの値によりパス上のどの位置かを指定することができます。
ScreenShot 2022 08 07 12 31 15↑Tracked Dollyが指定されている
マイケル
マイケル
PathPositionの値を変更してみると下記のように移動することが確認できます。
04 dolly camera↑PathPositionを変更した場合
エレキベア
エレキベア
これは中々楽しいクマね
CinemachineDollyCart
マイケル
マイケル
対してCinemachineDollyCartはカメラ以外のオブジェクトを移動させることを想定しており、
DollyTrackとDollyCartのスクリプトがアタッチされた空のオブジェクトが作成されます。
ScreenShot 2022 08 07 12 35 14↑DollyTrackとDollyCartが作成される
マイケル
マイケル
オブジェクトをDollyCartの子オブジェクトに設定することでパス上を動かすことができます。
この時、動かす速度はDollyCartスクリプトのSpeed変数で指定できます。
ScreenShot 2022 08 07 12 36 07↑動かす速度の設定
04 dolly cart↑実行すると速度に応じて自動で移動する
エレキベア
エレキベア
こっちは速度に応じて処理も用意されているクマね
ドリーパスを使用したカメラを指定秒数で切り替える
マイケル
マイケル
これらを活用してドリーパスを使用したカメラを切り替えてアニメーションを作成する方法について考えてみましょう!
05 dolly animation↑完成図
エレキベア
エレキベア
むむ、指定秒数で切り替えるならBlendListCameraでいけそうな気もするクマが
毎回パスの開始地点に戻すのが難しそうクマね・・・
マイケル
マイケル
そうなんだよね・・・
なので今回はCinemachineDollyCartを複数用意してスクリプト側で切り替えることにしました!
エレキベア
エレキベア
結局それしかないクマか・・・
マイケル
マイケル
下記のようにCinemachineDollyCartを二つ作成して、
更にDollyCartの子オブジェクトとしてVirtualCameraを作成します。
ScreenShot 2022 08 07 13 05 33↑DollyCartとVirtualCameraを作成
マイケル
マイケル
そして今回は動きを出すために
それぞれのDollyCartオブジェクトの速度は変更しておきます。
ScreenShot 2022 08 07 13 06 37
ScreenShot 2022 08 07 13 06 48
マイケル
マイケル
あとは下記のように指定秒数ごとに切り替えるスクリプトを作成することで
今回のような動きを実現することができます!
using System.Collections;
using Cinemachine;
using UnityEngine;
public class DollyCameraAnimation : MonoBehaviour
{
    [SerializeField] private CinemachineVirtualCamera virtualCamera1;
    [SerializeField] private CinemachineVirtualCamera virtualCamera2;
    [SerializeField] private CinemachineDollyCart dollyCart1;
    [SerializeField] private CinemachineDollyCart dollyCart2;
    private void Start()
    {
        // アニメーション開始
        StartCoroutine(DollyCameraAnimationCoroutine());
    }
    private IEnumerator DollyCameraAnimationCoroutine()
    {
        // 指定秒数ごとにカメラを切り替える
        while (true)
        {
            // dollyCart1の位置を戻してカメラを表示
            dollyCart1.m_Position = 0.0f;
            yield return new WaitForSeconds(0.5f);
            virtualCamera1.Priority = 1;
            virtualCamera2.Priority = -1;
            yield return new WaitForSeconds(2.0f);
            // dollyCart2の位置を戻してカメラを表示
            dollyCart2.m_Position = 0.0f;
            yield return new WaitForSeconds(0.5f);
            virtualCamera1.Priority = -1;
            virtualCamera2.Priority = 1;
            yield return new WaitForSeconds(2.0f);
        }
    }
}
↑切り替える処理の作成
ScreenShot 2022 08 07 13 09 49↑DollyCartとVirtualCameraをアタッチ
エレキベア
エレキベア
スクリプトを書いたとはいえこれだけの記述で
それっぽいカメラワークが作れるのはすごいクマね
マイケル
マイケル
一歩踏み込もうとすると用意されてる機能だけでは足りない部分が出てくるから、
こういった活用は必要になりそうだね!

おわりに

マイケル
マイケル
というわけで今回はCinemachineの活用法についてでした!
どうだったかな?
エレキベア
エレキベア
いろんなカメラワークが作れて楽しかったクマ〜〜〜
やっぱりCinemachineは便利クマね
マイケル
マイケル
デフォルトでもいろんな機能が用意されているし、
スクリプトでも自由に操作できるから積極的に使っていきたいね!
マイケル
マイケル
それでは今日はこの辺で!
アデュー!!
エレキベア
エレキベア
クマ〜〜〜〜

【Unity】Cinemachineでいくつかカメラワークを作ってみる 〜完〜

コメント