【Unity】2Dゲームでカメラをプレイヤーに追従させる方法

2Dでカメラを追従させる方法 Unity

こんにちは、ともくんのゲーム作り部屋にようこそ!

このページでは、

「2Dゲームにてカメラを追従させる方法を知りたい!」

「プレイヤーの移動にカメラを合わせたい!」

というお悩みの方に向けた内容となっています。

2Dアクションゲームやシューティングゲームなどでは、プレイヤーの移動に合わせてカメラも移動させることで、常にカメラの定位置にプレイヤーが配置される処理を作ることがあります。

カメラをプレイヤーに追従させる場合は、カメラとプレイヤーの座標位置において、相対関係を作ることで、プレイヤーの移動に合わせてカメラを移動させることができます。

また、2Dゲームでよくあるジャンプなど上に移動するアクションの時は、カメラを追従させないといったこともできます。

そこで、このページでは、Unityで2Dゲームを作る際に、プレイヤーの移動に合わせてカメラを追従させる方法について、まとめていきます。

この記事を書いた人

ゲーム作りを学び始めた一児のパパです。
このブログは、子供から「ゲームを作ってみたい!」と言われ、非プログラマーでゲーム作りをしたことない僕が、ゲーム作りの本を読んで独学でゲーム開発を学んでいるブログです。
同じように初めてゲーム作りをしている方と一緒に学んでいけるようなブログに出来たらいいなと思っています。
また、「このコードはおかしい」とか「もっと良い書き方があるよ!」などあれば、どんどん指摘して頂けると助かります。

2Dでカメラをプレイヤーに追従させる方法

ここでは、以下のような簡単な2Dアクション用のコースを作成して、プレイヤーの移動に合わせてカメラを追従させる処理を作っていきます。

現時点では、以下のようにプレイヤーをキー操作で移動したりジャンプしたりできるようにしています。

ただカメラが移動していないため、ステージの途中までしか表示されていません。

カメラを追従させる処理を作る

先ほどのプレイヤーの移動に合わせて、カメラを追従させる処理を作ってみます。

ここでは、

  • プレイヤーを中心にカメラを追従させる
  • プレイヤーを左下にしてカメラを追従させる
  • ジャンプの時にカメラを追従させないようにする処理

の3つをそれぞれを作ってみます。

プレイヤーを中心にカメラを追従させる

プレイヤーを常にゲーム画面の中心に置いた状態で、カメラを追従させるやり方になります。

カメラオブジェクトに対して、以下のスクリプトをアタッチします。

using UnityEngine;

public class CameraController : MonoBehaviour
{
    public GameObject player;
    Vector3 prePlayerPos;   // 前フレームでのプレイヤーの座標位置

    void Update()
    {
        if(player.transform.position != prePlayerPos)
        {
            transform.position = new Vector3(player.transform.position.x, player.transform.position.y, -10);
            prePlayerPos = player.transform.position;
        }
    }
}

まず、5行目でプレイヤーのオブジェクトを取得する変数playerを、public修飾子を付けて宣言します。

後ほどでいいのですが、カメラオブジェクトを選択した状態で、インスペクターウィンドウからプレイヤーの実体を入れてあげます。

そして、X座標とY座標において、カメラの座標位置とプレイヤーの座標位置が等しくなるように、12行目で「transform.position」を使って記述してあげます。

注意点として、Z軸の座標をプレイヤーと同じにしてしまうと、カメラに映らなくなるため、画面の手前側にカメラ位置を設定できるように、Z座標は「-10」を指定しています。

また、Updateメソッドは、フレーム毎に座標位置の更新処理が行われてしまうため、負担を軽減するためにプレイヤーの座標が移動したときにだけカメラを追従できるように、prePlayerPosという変数を使って、座標が変動したかどうかをif文で条件指定しています。

これで実際にゲームを実行してみると、

上のように、常にプレイヤーが真ん中にいる状態で、カメラを追従させることができました。

プレイヤーを左下にしてカメラを追従させる

今度は、プレイヤーを中心ではなく左下辺りに配置して、先のステージが分かるような形でカメラの移動を行ってみます。

先ほどのカメラのスクリプトを以下のように修正してみます。

using UnityEngine;

public class CameraController : MonoBehaviour
{
    public GameObject player;
    Vector3 prePlayerPos;

    void Update()
    {
        if(player.transform.position != prePlayerPos)
        {
            transform.position = new Vector3(player.transform.position.x + 5, player.transform.position.y + 2, -10);
            prePlayerPos = player.transform.position;
        }
    }
}

12行目で、カメラのX座標をプレイヤーの座標から「+5」、Y座標をプレイヤーから「+2」ずらす処理を行っています。

このようにプレイヤーの座標から相対的にずらしてあげることで、中心ではなく左下などのすこしずれた場所にプレイヤーを固定して表示させることができます。

実際にゲームを実行してみると、

プレイヤーが左下にいる状態で、常に固定することができています。

ジャンプの時はカメラを追従させないようにする処理

先ほどまでの作り方だと、プレイヤーがジャンプしたり高いところに移動すると、カメラの視点も上に移動することになりますが、ステージによっては全く下が見えなくなってしまうことがあります。

そこで、ジャンプやステージによる上移動の際はカメラを追従させないといった処理を作ることもできます。

もう一度カメラのスクリプトを修正してみます。

using UnityEngine;

public class CameraController : MonoBehaviour
{
    public GameObject player;
    Vector3 prePlayerPos;

    void Update()
    {
        if(player.transform.position != prePlayerPos)
        {
            transform.position = new Vector3(player.transform.position.x + 5, 0, -10);
            prePlayerPos = player.transform.position;
        }
    }
}

9行目のカメラの座標のX座標は先ほどと変わりませんが、Y座標を「0」に固定しています。

X座標はプレイヤーの移動と相対的に動くことになりますが、Y座標はプレイヤーがジャンプしても常に0のままとなります。

もう一度ゲームを実行してみると、

プレイヤーがジャンプしても、カメラは上下に移動せず、横にだけ動くようになりました。

ゴールしたら追従を解除する処理を作る

プレイヤーの移動に対して、カメラを追従させることができましたが、ステージをクリアした際などにこのカメラの追従を解除する場合があります。

そこで、ゴールの旗にプレイヤーが触れたら、カメラを追従させる機能を解除するという処理を作ってみます。

まず、ゴールの旗とプレイヤーが触れる処理をプレイヤーのスクリプトの中に記述していきます。(プレイヤーの移動処理などの記述は省略しています。)

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public bool isGoalling = false; // ゴールしているかどうかを判定する変数

    void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.name == "Flag")
        {
            isGoalling = true;
        }
    }
}

ゴールしたかどうかを判定する「isGoalling」というbool型の変数を5行目で作り、public修飾子を付けて他のスクリプトから変数にアクセスできるようにしておきます。

7行目でOnTriggerEnter2Dメソッドを使って、旗のオブジェクトにプレイヤーが触れた場合に、isGoallingをtrueに変更する処理を書いています。

なお、旗のオブジェクトに対して、コライダーコンポーネントの項目にある「isTrigger」にチェックを入れておく必要があります。

これでプレイヤー側の処理は終わったので、次はカメラのスクリプトに処理を加えていきます。

using UnityEngine;

public class CameraController : MonoBehaviour
{
    public GameObject player;
    Vector3 prePlayerPos;
    PlayerController playerController;

    void Start()
    {
        playerController = player.GetComponent<PlayerController>();
    }

    void Update()
    {
        if(player.transform.position != prePlayerPos && playerController.isGoalling == false)
        {
            transform.position = new Vector3(player.transform.position.x + 5, 0, -10);
            prePlayerPos = player.transform.position;
        }
    }
}

Startメソッドの中の11行目で、GetComponentメソッドを使って、プレイヤーのスクリプトである「PlayerController」を取得しています。

そして、カメラを移動させる処理をゴールする前までとしたいので、16行目のif文の中でPlayerControllerにある「isGoalling」の変数がfalseの時にだけ、カメラを移動させるようにしています。

これでゲームを実行してみると、

ゴールの旗に触れた後、プレイヤーは移動しますが、カメラはそこから動かなくなり、カメラの追従処理を解除することができています。

まとめ

このページでは、Unityで2Dゲームを作る際に、プレイヤーにカメラを追従させる方法についてまとめていきましたが、いかがでしたでしょうか?

2Dゲームでカメラを追従させる場合は、プレイヤーの座標位置に対して相対的にカメラの座標位置を決めることで、追従させることができます。

具体的には、カメラとプレイヤーの座標をtransform.positionの変数を使って、それぞれを相対的に処理することで、カメラを追従させることができます。

また、ゴール後などカメラの追従処理を止めたいといったことも、スクリプトから行うことができます。

なお、以下のページでは、3Dゲームでのカメラの追従方法を紹介していますので、合わせて参考にしてみてください。

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

コメント