4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Unity】Cinemachineカメラの俯瞰・アオリ角の最大値を制限する / CinemachineExtension のススメ

Last updated at Posted at 2022-06-10

目的

皆さん以下のような状況にあったことありませんでしょうか?

  • Cinemachine はすごく良い感じにカメラを設定してくれるけど、時々変な方向に向いて、どう調整すれば分からない

  • できれば敵を追従して欲しいけど、真上や真下には向いてほしくない

    • つまり、俯瞰とアオリの角度の最大値を制限したい!

 
少なくとも自分にはめちゃめちゃありました。ですので、それを簡単に修正する方法を共有したいと思います。
加えて、似たような「痒いところに手が届かない」時に、コードで Virtual Camera の結果を微調整する方法も、合わせて共有します。

※ この記事は、すでにある程度 Cinemachine を使ったことのあるかた向けです。

改善前

下記は修正前のカメラ挙動です。
修正前.gif
これはこれで綺麗で気持ちいいのですが、今回はこのカメラの俯瞰角を最大 25 度までと制限してみます。

要件

Cinemachine Virtual Camera の俯瞰・アオリ角( = Pitch 角)を制限したい

やり方

実は、Cinemachine には CinemachineExtension という、
各 Virtaul Camera の出力結果を簡単に修正する拡張コンポーネントがありました。

下の画像のように、出力結果を色々な方法で微調整するコンポーネントがたくさんあります。
extension.png

今回は CinemachineExtension を自作して、俯瞰 / アオリの角度を制限してみます。

コード

やり方はとても簡単です。
MonoBehaviour の代わりに、CinemachineExtension を継承して、PostPipelineStageCallback() を override するだけです。

CinemachineRestrictAngle.cs
using UnityEngine;

namespace Cinemachine
{
    [AddComponentMenu("")] // Hide in menu
    [ExecuteAlways]
    [SaveDuringPlay]
    public class CinemachineRestrictAngle : CinemachineExtension
    {
        /// <summary>
        /// field を public にすることで SaveDuringPlay が可能になる
        /// </summary>
        [Header("適用段階")]
        public CinemachineCore.Stage m_ApplyAfter = CinemachineCore.Stage.Aim;

        [Header("俯瞰角 閾値")]
        [Range(0f, 90f)]
        public float lowAngleThreshold = 80f;

        [Header("アオリ角 閾値")]
        [Range(0f, 90f)]
        public float highAngleThreshold = 80f;

        /// <summary>
        /// カメラパラメータ更新後に呼び出される Callback。ここで結果を微調整する。
        /// </summary>
        protected override void PostPipelineStageCallback(CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
        {
            if (stage != m_ApplyAfter) return;

            // カメラの X 軸回転を制限する
            var eulerAngles = state.RawOrientation.eulerAngles;
            eulerAngles.x = Mathf.Clamp(eulerAngles.x, -highAngleThreshold, lowAngleThreshold);
            state.RawOrientation = Quaternion.Euler(eulerAngles);
        }
    }
}

そうすると、上のコードのように、引数に CameraState state というものが渡ってきますが、この CameraState こそ、
VirtualCamera カメラの処理結果です

最終的に、CinemachineBrain は Priority の一番大きい VirtualCameraCameraState を取得して、
それを本物の Camera に適用します。
(遷移中の場合、前後のカメラの CameraState を Lerp して、適用します)
 
今回は俯瞰角を制限したいですので、
上のコードでは CameraState.RawOrientation を取得して、角度を clamp してまた戻しています。
これで、バーチャルカメラの計算結果を微調整して、角度を制限することが出来ます。

インスペクター設定

上のコードを CinemachineRestrictAngle.cs に保存すると、下記画像のように VirtualCamera の Extensions から選べるようになります。
extensionSettings.png
CinemachineRestrictAngle を選び、俯瞰とアオリ角の閾値を 25 度に設定します。
これで、俯瞰角・アオリ角の最大値を自由に調整することができます。

改善後 結果

改善後の結果です。
修正後.gif
前半は改善前と同じ画角の運び方をしていますが、
25 度を超えていたところの画角の角度は制限され、それ以上に下を向かなくなりました。

この記事のように、CinemachineExtension を継承すれば、Virtual Camera の結果を色々微調整することができます。

現に、カメラを壁などに埋め込ませないようにできるコンポーネント CinemachineCollider
公式で Extension として提供しています。

今回は俯瞰・アオリ角に最大値を付ける方法を説明しましたが、
ぜひ今度「こういう微調整の機能があったら良いな」と思った時、自作 CinemachineExtension を作ってみましょう!

4
0
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
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?