【Unity】キャラクターの向きを変えずに画面上で平行移動する

はじめに

ゲーム等を作成していると、カメラは基本的にキャラクターを中心に映すことが多いです。

しかし、例えばステータス画面等でキャラクターを左に、パラメータを右側に出したいというときに地味に困るのがカメラの設定です。

本記事ではキャラクターを正面に向かせつつ、上下左右に配置調整できるようにする方法を記載します。

問題点

まず、下記のようにキャラクターを少し左に寄せたいということを考えます。
(※これは完成図)

この時ぱっと思いつくのはカメラを少し右側に寄せることです。

しかし、普通にやるとこのようにキャラクターが若干左を向いているような印象になります。

これを補正する場合に通常であれば「キャラクターの向きをカメラに向ける」ということを考えますが、操作するものがキャラクターとカメラになるので、カメラに加えて、キャラクターのオブジェクト参照も必要になってしまいます。

なんとかカメラだけで実現できないのか?というのが今回の目的です。

実現方法

理屈は色々と難しいですが、カメラのprojectionMatrixを操作することで実現できそうです。

理屈に興味がある方は下記の記事がおすすめです。

[Unity]斜め(Oblique)の投影行列で空間を切り取る - Qiita
Oblique Matrix って日本語でなんて言うのだろ。まとにかく、斜めの投影行列(Oblique Projection Matrix)を使って空間を切り抜く効果を作ってみます。#まずは結果から…

この理屈を元にprojectionMatrixを操作するためのメソッドを作成し、カメラに下記のコンポーネントをアタッチします。

using UnityEngine;

/// <summary>
/// カメラのプロジェクションマトリクスにオフセットを適用するテスト用スクリプト。
/// オフセットはXおよびY方向に制限された範囲で調整可能。
/// </summary>
public class TestCameraScript : MonoBehaviour
{
    /// <summary>
    /// メインカメラの参照。Startで初期化される。
    /// </summary>
    private Camera MainCamera;

    /// <summary>
    /// プロジェクションマトリクスに適用するX方向のオフセット値(-1〜1)。
    /// </summary>
    [SerializeField][Range(-1f, 1f)]
    private float offsetX = 0f;

    /// <summary>
    /// プロジェクションマトリクスに適用するY方向のオフセット値(-1〜1)。
    /// </summary>
    [SerializeField][Range(-1f, 1f)]
    private float offsetY = 0f;

    /// <summary>
    /// Startは最初のフレームの前に一度だけ呼び出される。
    /// メインカメラの参照を取得する。
    /// </summary>
    void Start()
    {
        MainCamera = Camera.main;
    }

    /// <summary>
    /// 毎フレーム呼び出される。
    /// オフセットをカメラに適用する。
    /// </summary>
    void Update()
    {
        ApplyProjectionOffset(MainCamera, offsetX, offsetY);
    }

    /// <summary>
    /// 指定したカメラにプロジェクションマトリクスのオフセットを適用する。
    /// オフセットが0の場合、マトリクスをリセットする。
    /// </summary>
    /// <param name="cam">対象のカメラ。</param>
    /// <param name="offsetX">X方向のオフセット。</param>
    /// <param name="offsetY">Y方向のオフセット。</param>
    private void ApplyProjectionOffset(Camera cam, float offsetX, float offsetY)
    {
        if (offsetX == 0 && offsetY == 0)
        {
            cam.ResetProjectionMatrix();
            return;
        }

        cam.ResetProjectionMatrix();
        var mat = cam.projectionMatrix;
        mat[0, 2] = offsetX;
        mat[1, 2] = offsetY;
        cam.projectionMatrix = mat;
    }
}

コンポーネントをアタッチするとインスペクタにスライダーが表示されるので、これを操作することでキャラクター向きを変えることなく、画面上の位置を調整することができます。

さいごに

本記事の内容は以上です。

最近はパラメータ表示時などに2Dイラストを使わずに、3Dモデルで対応することも増えている印象です。
そのようなことをする際に実現の役に立てば幸いです。

最後までお読みいただきありがとうございます!

コメント

タイトルとURLをコピーしました