Unity 6の2Dで上下左右・斜めの8方向に移動する方法(normalizedで斜め移動をそろえる)

広告

この記事は「Unity 6 2D移動の総合ガイド」の一部です。前の記事では、左右に移動しました。今回は上下も加えて、8方向に移動します。トップダウン型のRPGやシューティングゲームで使う移動です。

この記事で分かること

  • X軸とY軸の入力をまとめて、移動方向をVector2で表す方法
  • 斜め移動が速くなってしまう理由
  • normalizedで、どの方向でも同じ速さにする方法

1. 完成する動き

WASDキーを使って、上下左右と斜めの8方向に移動できます。斜めに進んでも、速さは上下左右と同じです。

キー入力で四角いオブジェクトが上下左右の方向に移動する動作

2. 前提と準備

共通の準備は総合ガイドの「共通の準備」をご覧ください。Input Systemの設定は、前の記事と同じです。

今回もTransformを直接動かす方法なので、Rigidbody 2Dは不要です。前の記事のHorizontalMoveが付いている場合は、取り外してください。

3. スクリプトを作る

EightDirectionMoveという名前でスクリプトを作り、Playerに取り付けます。

EightDirectionMove.cs

using UnityEngine;
using UnityEngine.InputSystem;

public class EightDirectionMove : MonoBehaviour
{
    [SerializeField] float speed = 5f;

    void Update()
    {
        if (Keyboard.current == null)
            return;

        float x = 0f;
        float y = 0f;

        if (Keyboard.current.aKey.isPressed)
            x -= 1f;

        if (Keyboard.current.dKey.isPressed)
            x += 1f;

        if (Keyboard.current.sKey.isPressed)
            y -= 1f;

        if (Keyboard.current.wKey.isPressed)
            y += 1f;

        Vector2 direction = new Vector2(x, y);

        direction = direction.normalized;

        transform.position +=
            (Vector3)direction * speed * Time.deltaTime;
    }
}

4. コードの解説

① xとyで入力をまとめる

前の記事では、左右を表すmoveXだけでした。今回は、左右を表すxと、上下を表すyを用意します。

キー変化
Axから1引く
Dxに1足す
Syから1引く
Wyに1足す

=で代入せずに-=と+=を使っている点にも注目してください。反対のキーを同時に押すと打ち消し合い、停止します。

② Vector2 direction = new Vector2(x, y);

xとyをまとめて、移動する方向を表すベクトルにします。例えばDとWを同時に押すと、(1, 1)になります。

③ なぜnormalizedが必要なのか

右方向だけに進む場合のベクトルは、(1, 0)です。このベクトルの長さは1です。

ところが右上に進む場合は(1, 1)で、長さは約1.414になります。

方向ベクトル長さ
右(1, 0)1
右上(1, 1)約1.414

何もしないと、斜め移動が約1.4倍速くなってしまうことになります。そこで次のようにします。

direction = direction.normalized;

normalizedは、ベクトルの長さを1にそろえる機能です。これにより、進む方向がどこでも、ベクトルの長さが1にそろいます。何も押していないときは(0, 0)のままで、そのまま停止します。

④ (Vector3)direction

transform.positionはVector3ですが、directionはVector2です。そのため、(Vector3)と書いてVector3に変換してから足しています。変換するとZは0になり、Z方向には動きません。

5. よくあるつまずき

症状確認すること
斜めだけ速いdirection.normalizedの行を忘れていないか
エラー「Cannot implicitly convert type」(Vector3)の変換を書いているか
キーが反応しないActive Input Handlingの設定。Gameビューにフォーカスがあるか
勝手に動く前の記事のスクリプトが取り付いたままになっていないか

6. 試してみよう:normalizedを外して比べる

direction = direction.normalized;の行をコメントアウトして、斜めに移動してみましょう。右に進むときと比べて、斜めの方が明らかに速くなります。違いを自分の目で確かめると、理解が深まります。

7. 練習問題

WASDキーに加えて、矢印キーでも移動できるようにしてみましょう。

ヒント

  • 前の記事では、||(または)でキーをつなぎました。
  • 上下の矢印キーはupArrowKeyとdownArrowKeyです。

解答例(まず自分で試してから見ましょう)

if (Keyboard.current.aKey.isPressed ||
    Keyboard.current.leftArrowKey.isPressed)
    x -= 1f;

if (Keyboard.current.dKey.isPressed ||
    Keyboard.current.rightArrowKey.isPressed)
    x += 1f;

if (Keyboard.current.sKey.isPressed ||
    Keyboard.current.downArrowKey.isPressed)
    y -= 1f;

if (Keyboard.current.wKey.isPressed ||
    Keyboard.current.upArrowKey.isPressed)
    y += 1f;

この書き方では、Aと左矢印を同時に押すと、xから2引かれてしまいますが、normalizedで長さが1にそろうため、速さは変わりません。

8. まとめ

  • xとyの入力をVector2にまとめて、移動方向を表す
  • 斜めのベクトルの長さは約1.414なので、そのままだと斜めだけ速くなる
  • normalizedで長さを1にそろえれば、どの方向でも同じ速さになる

次の記事では、いよいよ物理演算(Rigidbody2D)を使って移動します。

訪問数 4 回, 今日の訪問数 4回

広告