【Unity】Cinemachineカメラをスプラインに沿って動かす

こじゃらこじゃら

CinemachineのバーチャルカメラをSplinesパッケージのスプラインに沿って動かしたいの…

このはこのは

連携用のスクリプトを書けば可能だわ。Cinemachine 3.xからは標準でサポートされているわ。

CinemachineのバーチャルカメラをSplinesパッケージのスプラインに沿って動かす方法の解説記事です。

実現方法はCinemachineのバージョンによって異なり、それぞれ次のようになります。

バージョン毎の実現方法
  • Cinemachine 2.x – スプラインと連携するためのスクリプトを実装してTracked Dollyで動かす
  • Cinemachine 3.xSpline Dolly(既存機能)を使う

Cinemachineにはカメラワークの機能の一つとして、パスに沿ってカメラを動かす機能が提供されています。

参考:Using dolly paths | Cinemachine | 2.9.5

本記事では、次のようにSplinesパッケージのスプラインに沿ってカメラを動かす方法について解説していきます。

Cinemachine 2.xおよび、Cinemachine 3.xのバージョンそれぞれについて実現方法を解説します。

動作環境
  • Unity 2022.2.16f1
  • Cinemachine 2.9.7
  • Cinemachine 3.0.0-pre.7
  • Splines 2.2.1

この作品はユニティちゃんライセンス条項の元に提供されています

スポンサーリンク

前提条件

事前にCinemachineパッケージとSplinesパッケージがインストールされているものとします。

また、Unity 2022.2以降でプロジェクトが開かれているものとします。

本記事では、次のように予め作成されたスプラインに沿ってCinemachineのバーチャルカメラを移動させるものとします。

Cinemachineの基本的な使い方は、以下記事をご覧ください。

Splines パッケージの導入方法およびスプラインパスの作成方法については、以下記事をご覧ください。

Cinemachine 2.x以前での実現方法

このバージョンでは、Splinesパッケージのスプラインに沿ってカメラを動かす公式の手段は提供されていないため、連携するためのスクリプトを実装する必要があります。

作業の流れは以下の通りです。

作業の流れ
  • CinemachinePathBase継承クラス(コンポーネント)を実装する
  • 上記コンポーネントを適当なゲームオブジェクトにアタッチし、スプラインを設定
  • Cinemachineのバーチャルカメラ側に上記移動パスをTracked Dollyとして設定

上から順番に手順を解説していきます。

CinemachinePathBase継承クラスの実装

Cinemachine 2.xまでは、Tracked Dollyと呼ばれるパスに沿ってカメラを移動させる機能があります。 [1]

参考:Tracked Dolly | Cinemachine | 2.9.7

カメラの移動経路には、Cinemachine PathCinemachine Smooth Pathなどのコンポーネントを指定出来るようになっています。

指定する移動経路はCinemachinePathBase継承クラスであれば良いので、独自実装したコンポーネントを指定することもできます。

Splines パッケージで作成した経路に沿ってカメラを移動させたい場合は、SplineContainerコンポーネントなどから計算される位置や向き情報を中継して渡すCinemachinePathBaseクラスを実装すればよいことになります。

以下、スクリプトの実装例です。

MySplineDolly.cs
using UnityEngine;
using UnityEngine.Splines;
using Cinemachine;

/// <summary>
/// スプラインを使ったカメラの移動経路
/// </summary>
public class MySplineDolly : CinemachinePathBase
{
    // カメラの移動経路(スプライン)
    [SerializeField] private SplineContainer _spline;

    // パスのローカル空間における位置
    public override Vector3 EvaluateLocalPosition(float pos)
    {
        return _spline.Spline.EvaluatePosition(pos);
    }

    // パスのローカル空間における傾き
    public override Vector3 EvaluateLocalTangent(float pos)
    {
        return _spline.Spline.EvaluateTangent(pos);
    }

    // パスのローカル空間における向き
    public override Quaternion EvaluateLocalOrientation(float pos)
    {
        return Quaternion.LookRotation(
            EvaluateLocalTangent(pos),
            _spline.Spline.EvaluateUpVector(pos)
        );
    }

    // パスの位置の最小値
    public override float MinPos => 0;

    // パスの位置の最大値
    public override float MaxPos => 1;

    // パスはループしているかどうか
    public override bool Looped => _spline.Spline.Closed;

    // パスの解像度
    public override int DistanceCacheSampleStepsPerSegment => m_Resolution;

    // 直近位置の検索
    public override float FindClosestPoint(Vector3 p, int startSegment, int searchRadius, int stepsPerSegment)
    {
        // パスのローカル空間における位置に変換
        p = _spline.transform.InverseTransformPoint(p);
        
        // スプラインの最近接点を求める
        SplineUtility.GetNearestPoint(
            _spline.Spline,
            p,
            out _,
            out var t
        );

        return t;
    }
}

上記をMySplineDolly.csという名前でUnityプロジェクトに保存すると使用可能になります。

コンポーネントの配置・設定

作成したパスコンポーネント(例ではMySplineDolly.cs)を適当なゲームオブジェクトにアタッチし、インスペクターからスプライン(SplineContainerコンポーネント)を指定します。

必要に応じてパスの解像度(Resolution)やGizmo上での表示色(Apperance)を設定してください。

バーチャルカメラ側の設定

Cinemachineのバーチャルカメラに対し、前述の定義したパスに沿って移動させる設定を適用していきます。

まず、シーン上にバーチャルカメラが配置されていなければ、ヒエラルキー左上の+アイコン(またはトップメニューのGameObject)よりCinemachine > Virtual Cameraの順に選択し、バーチャルカメラを配置します。

すると、ヒエラルキー上にバーチャルカメラのオブジェクトが追加されます。

該当のバーチャルカメラのBody項目Tracked Dollyを設定します。また、設定後に出現するPath項目に前述のパスコンポーネント(例ではMy Spline Dolly)を指定します。

無事に設定できると、バーチャルカメラを選択した状態で次のような梯子状のレールが表示されます。

必要に応じて、Look At(注視対象のオブジェクト)を指定します。

実行結果

次のように、Path Positionの値を変更すると、パスに沿ってカメラが動くようになりました。

自動追従させる

キャラクターなどを追従させたい場合は、バーチャルカメラのBody > Auto Dolly > Enabledチェックを入れFollow項目追従対象のオブジェクトを指定すれば良いです。

必要に応じて、Position Offset項目(位置のオフセット値)を調整してください。Search RadiusとSearch Resolution項目は今回は使用しません。

参考:Tracked Dolly | Cinemachine | 2.9.7

実行結果

キャラクターに追従するようにパスに沿ってカメラが移動するようになりました。

スクリプトの説明

前述の手順で登場した連携用スクリプトについて説明します。

SplinesパッケージのスプラインをCinemachineのドリーパスとするために、まず以下でSplineContainerコンポーネントへの参照を受け取ります。

// カメラの移動経路(スプライン)
[SerializeField] private SplineContainer _spline;

ドリーパスとして機能させるために、CinemachinePathBase継承クラスを実装します。

/// <summary>
/// スプラインを使ったカメラの移動経路
/// </summary>
public class MySplineDolly : CinemachinePathBase

スプライン上の位置や向きをカメラのパスとして返すために、以下のようにメソッドを実装します。

// パスのローカル空間における位置
public override Vector3 EvaluateLocalPosition(float pos)
{
    return _spline.Spline.EvaluatePosition(pos);
}

// パスのローカル空間における傾き
public override Vector3 EvaluateLocalTangent(float pos)
{
    return _spline.Spline.EvaluateTangent(pos);
}

// パスのローカル空間における向き
public override Quaternion EvaluateLocalOrientation(float pos)
{
    return Quaternion.LookRotation(
        EvaluateLocalTangent(pos),
        _spline.Spline.EvaluateUpVector(pos)
    );
}

いずれも指定された位置(0~1の範囲)に基づき、SplineContainerのローカル空間における位置傾きをそのまま返しています。

そして、以下で直近位置を返すメソッドもオーバーライドして実装しています。

// 直近位置の検索
public override float FindClosestPoint(Vector3 p, int startSegment, int searchRadius, int stepsPerSegment)
{
    // パスのローカル空間における位置に変換
    p = _spline.transform.InverseTransformPoint(p);
    
    // スプラインの最近接点を求める
    SplineUtility.GetNearestPoint(
        _spline.Spline,
        p,
        out _,
        out var t,
        m_Resolution
    );

    return t;
}

上記メソッドを実装しなくても最低限機能はしますが、Splinesパッケージでも直近位置を求める専用メソッドが提供されているため、こちらを使用するようにしています。

Cinemachine 3.x以降での実現方法

Cinemachine 2.x系ではSplinesパッケージのスプラインと連携するには独自のパスクラスを実装する必要がありました。

Cinemachine 3.x系以降では、このようなスクリプトを実装せずともスプライン連携できるようになりました。ただし、3.x系はまだpre-release版で正式リリースされたわけではありません(2023/5/21現在)。

本記事では、インストールから簡単な使い方までを解説します。

※以降手順はCinemachine 3.xが正式リリースされた時点で内容を更新する予定です

Cinemachine 3.x pre-releaseのインストール

次のいずれかの方法でインストール可能です。

  • manifest.jsonファイルを直接編集する
  • Package Managerから名前とバージョン指定でインストールする

参考:Official – Announcing Cinemachine 3.0 – Unity Forum

次の方法1または2の片方のみの手順を実施してください。

方法1 : manifest.jsonを直接編集する

以下パスのJSONファイルをテキストエディタなどで開きます。

[Unityプロジェクトフォルダ]/Packages/manifest.json

そして、Cinemachineパッケージの行のバージョンを修正して保存します。

修正前

{
  "dependencies": {

・・・(中略)・・・

    "com.unity.cinemachine": "2.9.1",

・・・(中略)・・・

}

修正後(3.0.0-pre.7にする場合)

{
  "dependencies": {

・・・(中略)・・・

    "com.unity.cinemachine": "3.0.0-pre.7",

・・・(中略)・・・

}

これでUnityエディタをアクティブにすればインストールされます。

方法2 : Package Managerからインストールする

トップメニューのWindow > Package Managerの順に選択し、Package Managerウィンドウを開きます。

左上の+アイコン > Add package by name…の順に選択し、以下の通り入力してAddボタンをクリックします。

Namecom.unity.cinemachine
Version (optional)3.0.0-pre.7
Cinemachine 3.0.0-pre.7をインストールする場合

最終的に、以下のように3.x.x-pre.xのようなバージョンのCinemachineが表示されていれば成功です。

注意

Cinemachine 3.xをインストールすると、前述のサンプルスクリプトはコンパイルエラーとなります。3.x系でも使えるようにするには、以下行を修正してください。

修正前

MySplineDolly.cs
using Cinemachine;

修正後

MySplineDolly.cs
using Unity.Cinemachine;

名前空間が変更されています。

参考:Upgrading a Project from Cinemachine 2.X | Cinemachine | 3.0.0-pre.7

Cinemachine Cameraの配置・設定

ヒエラルキーの+アイコン > Cinemachine > Cinemachine Cameraの順に選択して、Cinemachine Cameraを配置します。

Cinemachine CameraコンポーネントTracking Target項目追従対象を指定します。

例ではLookPosを指定しています。

Position Control項目Spline Dollyを指定します。

すると、Cinemachine Cameraの下にCinemachine Spline Dollyコンポーネントが追加されます。

Spline項目スプライン(Spline)コンポーネントを指定します。

必要に応じてAutomatic DollyDamping項目を調整しておきます。

例えば次のようにAutomatic Dollyにチェックを入れMethodにNearest Point To Targetを指定し、DampingのPositionに1などの大きな値を指定すると緩やかにパスに沿ってカメラがターゲット追従するようになります。

設定の詳細は以下リファレンスをご確認ください。

参考:Spline Dolly | Cinemachine | 3.0.0-pre.7

また、本記事ではキャラクターにカメラを向けるため、Cinemachine CameraコンポーネントのRotation Control項目Rotation Composerを指定することとします。

メモ

Cinemachine 3.x以降では、2.x以前で使用されていたTracked Dollyが非推奨になり、代わりに当手順のSpline Dollyを使う方法が推奨されています。

実行結果

Cinemachine 2.x系のTracked Dolly同様にスプラインに沿ってカメラが移動するようになりました。

さいごに

Cinemachine 3.x以降では、標準でSplinesパッケージのスプラインに沿ってカメラを移動させる方法がサポートされ、推奨されるようになりました。

Cinemachine 2.x以前ではこのような連携はサポートされていないため、Tracked Dollyとスプライン連携用のスクリプトを実装して対応する必要があります。

Cinemachine 3.x系でもTracked Dollyによるカメラワークは非推奨ながら可能です。

関連記事

参考サイト

スポンサーリンク