Menu
CoddyTech

視線の方向へ移動

CoddyのUnityジャーニー「本格的なゲームを作る」セクションの一部。レッスン 41/56。

カメラがプレイヤーを斜めから見ているとき、矢印キーを押すと、画面上で見える方向にプレイヤーが動くようにします。上を押すとカメラから遠ざかり、右を押すとカメラの右方向へ進みます。ワールドの軸で同じ動きになるのは、カメラが +z 方向を向いているときだけです。そこで、カメラ自身の方向である cam.forward と cam.right を使って移動を組み立てます。

まず、これらの方向を整える必要があります。プレイヤーを見下ろすカメラの forward は地面に向いているので、地面に沿った成分だけを残すために y を 0 にします。残ったベクトルは長さが 1 より短くなります。カメラが 30 度下を向いている場合は約 0.87 となり、プレイヤーの移動速度が遅くなってしまうため、正規化します。このプレイヤー移動処理は、レベルの一角を見下ろすメインカメラに追従します。

Transform cam = Camera.main.transform;

Vector3 forward = cam.forward;
forward.y = 0f;
forward.Normalize();
Vector3 right = cam.right;
right.y = 0f;
right.Normalize();

Vector3 move = forward * Input.GetAxisRaw("Vertical") + right * Input.GetAxisRaw("Horizontal");
if (move.magnitude > 1f) move.Normalize();   // 斜め移動でも速くならない
controller.Move(move * speed * Time.deltaTime);

Camera.main は MainCamera タグが付いたカメラです。2つの方向は毎フレーム読み取られるため、カメラが回転しても操作方向は正しく保たれます。上と右を同時に押すと、直角に交わる2つの単位ベクトルが加算され、長さは約 1.41 になります。そのため、移動ベクトルの長さが 1 を超えた場合に正規化します。

challenge icon

チャレンジ

中級

カメラはプレイヤーの周りをゆっくり回る(CameraRig.csは準備済み)ため、画面上ではワールドの軸が回り続けます。矢印キーでカメラを基準にプレイヤーを歩かせるように、重力がすでに記述されているMover.csを変更しましょう。インスペクターでspeed(4)と、カメラのTransformであるcamを設定します。

  • 上キーで地面に沿ってカメラから遠ざかり、下キーでカメラに近づき、右キーと左キーでそれぞれカメラの右と左へ進みます。斜め方向も含め、どの方向にも毎秒speed単位で進みます。ただし、カメラはプレイヤーを見下ろしています。
  • 歩いている間、プレイヤーは進行方向を向きます。停止しても、その向きを保ちます。

プレイを押し、カメラが回る間に歩き回ってから、チェックを押しましょう。

自分で試してみよう

using UnityEngine;

public class Mover : MonoBehaviour
{
    public float speed = 4f;
    public float gravity = -15f;
    public Transform cam;

    CharacterController controller;
    float verticalSpeed;

    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    void Update()
    {
        if (controller.isGrounded && verticalSpeed < 0f)
        {
            verticalSpeed = -2f;
        }
        verticalSpeed += gravity * Time.deltaTime;

        // ワールド座標の軸に沿って移動する:camを基準に移動し、進行方向を向くようにする
        Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
        move.y = verticalSpeed;
        controller.Move(move * Time.deltaTime);
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

本格的なゲームを作るのすべてのレッスン