LoginSignup
3
2

【Unity】Cinemachine と Input System で作るお手軽 TPS カメラ

Last updated at Posted at 2023-12-05

本記事は Advent Calendar 2023 「Unity #2」 6 日目の記事です。

【5 日】unsafeでアンマネージドな構造体でポインタアクセスとポリモーフィズムのテスト@fukaken5050 さん)
【6 日】本記事
【7 日】AI だけでシューティングゲームを作る(@k-taro56 さん)


お久しぶりです。Qiita。
イキテマス・シレット。
ikitemasu.png

はじめに

今回は Cinemachine × Input System というモダンな組み合わせを利用しつつ、できるだけシンプルに TPS(三人称視点)カメラを構築する方法の紹介です。

完成系のイメージ
demo.gif

Cinemachine と Input System はそれぞれ素晴らしいライブラリですが、理解するのが難しめだと思います。
なのでそれらを合わせて使おうとなると 1 + 1 = 200 となり 10 倍のパワーで襲ってくることになり頭を悩ませることに…。

私自身十分理解しているとは言えず、それゆえ「細かいことはいい!とりあえずモダンにお手軽に作りたいんだよ!」という人向けの記事になります。(いいんか…?)

今回使ったバージョン

  • Unity: 2022.3.7f1
  • Cinemachine: 2.9.7
  • Input System: 1.6.3

また、サンプルプロジェクトを GitHub 上にアップしていますので、必要に応じて参考にしてください。

準備

パッケージのインストール

Package Manager で Cinemachine および Input System のパッケージをインストールしていることを前提とします。
image.png

インストール方法は他の Unity 公式パッケージと同じように Unity Registry の一覧から探して追加すれば OK です。
詳しくは公式のドキュメントを参照してください。

シーンとキャラクターの用意

適当なシーンに適当なキャラクターを配置しておいてください。
今回キャラ制御については本題ではないので、最悪動かない Cube とかでも大丈夫です。
超適当なキャラクターコントローラーでよければ動作テスト用にこちらのスクリプトを使って頂いても大丈夫です。

作り方

カメラの作成

Cinemachine でカメラを作ります。
さあ、Cinemachine Free Look Camera を作成しま…せん
もちろんそれも構わないのですが、今回は可能な限りシンプルにいきたいのでより設定がしやすい Cinemachine Virtural Camera でやることを考えます。

Hierarchy ウィンドウの + ボタンなどから Cinemachine -> Virtual Camera を選択します。
image.png

作成したらインスペクターから以下の通り設定していきましょう。

Body の設定

対象に対して一定距離を保ち続ける Framing Transposer にし、以下のように設定します。

項目 設定値 補足
Tracked Object Offset 0, 0, 0 ここは変えないことを推奨します。Cinemachine Collider とかを合わせて使ったときに正しくぶつかってくれなくなるため。
X Damping 0 上下左右にカメラの遅れがあるとキャラ移動方向にずれが生じるため消します。
Y Damping 0 同上
Z Damping 0.2 カメラ前後方向の遅れですが、キャラの移動速度次第でめり込んだりしてしまうため下げて遅れにくくします。好みの値をどうぞ。
Camera Distance 3 好みの距離をどうぞ。

image.png

Aim の設定

入力に応じて視線をコントロールできる POV にし、以下のように設定します。

項目 設定値 補足
Vertical Axis > Speed 1 as Input Value Gain Input System でデバイスごとの調整を行うため、ここでは基準となる値を入力します。
Vertical Axis > Input Axis Value > Invert OFF 同上
Horizontal Axis > Speed 1 as Input Value Gain 同上
Horizontal Axis > Input Axis Value > Invert OFF 同上

image.png

入力の作成

Input System で入力を作ります。
入力を高度に抽象化してくれるのが Input System のいいところなので様々なデバイスに簡単に(本当に簡単かは諸説あり)対応できます。今回はマウスを想定して作成します。

  1. Project ウィンドウで右クリックし Create -> Input Actions を選択して inputactions アセットを作成します。
    または、既存のものがあるならそれを開きます。
    image.png

  2. 作成した inputactions をダブルクリックして開き、Action Maps の + ボタンを押して操作用のマップを作ります。仮に Player としました。
    image.png

  3. Actions からカメラ操作アクションを追加・編集します。仮に Look としました。
    image.png

  4. Action Properties の Action Type と Control Type をそれぞれ Value と Vector2 にします。
    image.png

  5. Look の下に Binding を追加・編集します。今回はマウス操作想定で Pointer -> Delta を選択しました。
    そうしたら Processers に Invert Vector 2 と Scale Vector 2 を追加して以下のように値を設定してください。

    項目 設定値 補足
    Invert Vector 2 -> Invert X OFF 入力をカメラ視線移動の上下左右と合わせたい場合。カメラ位置移動の上下左右と合わせる方が好みなら逆で。
    Invert Vector 2 -> Invert Y ON 同上
    Scale Vector 2 -> X 0.3 好みの感度をどうぞ。
    Scale Vector 2 -> Y 0.2 同上

    image.png

  6. Save Asset ボタンを押して保存します。
    image.png

カメラと入力の接続

Cinemachine Virtural Camera のゲームオブジェクトで Add Component ボタンを押して、Cinemachine Input Provider を選択します。
image.png

XY Axis に前述した inputactions の Look をドラッグアンドドロップします。
image.png

カメラをキャラクターにセット

  1. カメラがターゲットにする Transform を用意します。
    Hierarchy ウィンドウでプレイヤーオブジェクトを右クリックし、Create Empty を選択します。名前を仮に FocusTarget としました。
    image.png
  2. 好みの相対位置に調整します。今回は Position > Y を 1 にしました。
    image.png
  3. Cinemachine Virtural Camera の FollowLook At に先ほど作ったターゲットをドラッグアンドドロップします。
    image.png

完成!

Unity のプレイボタンを押してマウスを動かしてみましょう。
冒頭の gif のようにキャラ回りを移動できると思います。
ということでノーコードで TPS カメラができてしまいましたね!🙌

それでは、よい TPS ライフを!!

Z 方向は?

勘のいいガキは嫌いです。 聡明な皆様はお気づきでしょう…上で掲載した Cinemachine Input Provider には Z Axis もあります。つまり、ドリーやズームでキャラとの距離感を調整する方向軸ですね。
image.png

これはいかにもそのまま動作してくれそうなのですが、調べたり試した感じではそのまま使えませんでした。  
なのでここで少しだけスクリプトを書くことになります。🖊️😢

CinemachineDollyInputProvider.cs
using Cinemachine;
using UnityEngine;

/// <summary>
/// CinemachineFramingTransposer のカメラ前後方向のコントロールを付与する
/// </summary>
public class CinemachineDollyInputProvider : MonoBehaviour
{
    [SerializeField]
    private CinemachineVirtualCamera _cinemachineVirtualCamera = null;
    
    [SerializeField]
    private CinemachineInputProvider _cinemachineInputProvider = null;
    
    [SerializeField]
    private float _sensitivity = 1f;
    
    [SerializeField]
    private float _minDistance = 1f;
    
    [SerializeField]
    private float _maxDistance = 5f;


    public float Sensitivity
    {
        get => _sensitivity;
        set => _sensitivity = value;
    }

    private void OnEnable()
    {
        _cinemachineInputProvider.ZAxis.action.Enable();
    }

    private void OnDisable()
    {
        _cinemachineInputProvider.ZAxis.action.Disable();
    }

    private void Awake()
    {
        var cinemachineComponent = _cinemachineVirtualCamera.GetCinemachineComponent(CinemachineCore.Stage.Body);
        if (cinemachineComponent is CinemachineFramingTransposer cinemachineFramingTransposer)
        {
            _cinemachineInputProvider.ZAxis.action.performed += context =>
            {
                float distance = Mathf.Clamp(cinemachineFramingTransposer.m_CameraDistance + context.ReadValue<float>() * _sensitivity, _minDistance, _maxDistance);
                cinemachineFramingTransposer.m_CameraDistance = distance;
            };
        }
        else
        {
            Debug.LogWarning($"{nameof(CinemachineFramingTransposer)} が存在しません。");
        }
    }
}

見ていただいている通り、このスクリプトがやっていることは単純です。 Cinemachine Input Provider に割り当てられた Z 入力アクションを Framing TransposerCamera Distance に流し込む処理を記述しています。

このスクリプトを Cinemachine Virtural Camera のゲームオブジェクトに追加し、Cinemachine Virtual CameraCinemachine Input Provider をドラッグアンドドロップで割り当てます。
image.png

上で作った inputactions アセットを再度開き、

  1. Actions からカメラドリー操作アクションを追加します。仮に LookDolly としました。
    image.png

  2. Action Properties の Action Type と Control Type をそれぞれ Value と Axis にします。
    image.png

  3. LookDolly の下の Binding を編集します。マウス操作想定ですので Mouse -> Scroll/Y を選択しました。
    そうしたら Processers に Invert と Scale を追加して以下のように値を設定してください。

    項目 設定値 補足
    Scale -> Factor 0.003 好みの感度をどうぞ。

    image.png

  4. Save Asset ボタンを押して保存します。

この inputactions の LookDolly を Cinemachine Input ProviderZ Axis にドラッグアンドドロップします。
image.png

本当に完成!

Unity のプレイボタンを押してマウスを動かしてみましょう。
この gif のようにキャラ回りを移動したり近づいたり離れたりできると思います。
demo_dolly.gif

おわりに

思ったよりボリュームが大きくなってしまいました…。ここまで読んでいただいてありがとうございます。
素直なフローを踏んでいると思うので、要件によっては十分ベストプラクティスの一つになりえるのではないでしょうか…!

改めて、よい TPS ライフを!!

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2