# Timmyがカメラに相対的に移動する

これでカメラが自由に回転できるようになったが、今度何かおかしい現象が発生。

カメラが主人公の後ろにある場合は、何とか正しく動きますが、真横、または正面から見ると入力する、主人公の動きが変に感じる。なぜなら、キャラクターがカメラの位置を関係なく、世界のXZ軸に沿って動くので、カメラの向きが変わったら、おかしく感じる。

この問題を解決するには、世界に絶対的に動くのではなく、カメラの向きに合わせて相対的に移動すること。

<table border="1" id="bkmrk-%E3%81%93%E3%81%AE%E5%A0%B4%E5%90%88%E3%81%AF%E3%80%81%E3%82%AB%E3%83%A1%E3%83%A9%E5%89%8D%E6%96%B9%EF%BC%88%E9%9D%92%E3%81%84%E7%9F%A2%E5%8D%B0%EF%BC%89%E3%81%8C%E4%B8%96%E7%95%8C" style="border-collapse: collapse; width: 100%; height: 389.5px;"><colgroup><col style="width: 50%;"></col><col style="width: 50%;"></col></colgroup><tbody><tr style="height: 389.5px;"><td style="height: 389.5px;">![image.png](https://class.illogic.games/uploads/images/gallery/2026-05/scaled-1680-/NI7image.png)

</td><td style="height: 389.5px;">![image.png](https://class.illogic.games/uploads/images/gallery/2026-05/scaled-1680-/Vlnimage.png)</td></tr><tr><td>この場合は、カメラ前方（青い矢印）が世界のZ軸と並行になっているので、「W」キーを押すと、正しく移動する

</td><td>一方、Heightを回すと、カメラ前方の向きが変わり、「W」を押すと、世界に対して斜め（青い矢印の向き）に移動してほしい</td></tr></tbody></table>

## スクリプト

`PlayerMove` を編集し、世界のXZではなく、Heightの回転を従って移動させましょう。これには、[Transform コンポネントの「forward」と「right」を使いましょう！](https://nekojara.city/unity-object-direction)

```c
using UnityEngine;

// プレーヤーの移動を処理する
public class PlayerMove : MonoBehaviour
{
    // カメラのY軸回転状況を知りたい
    [SerializeField] 
    private Transform cameraYRot;

    // （省略）
    
    private void Update()
    {
        // 何も入力がない前提で、速度をゼロにする
        velocity = Vector3.zero;
        
        // A/S（水平入力）を取得し、3D空間のX軸に割り当てる
        // velocity.x = Input.GetAxis("Horizontal");

        // W/D (垂直入力)を取得し、3D空間のZ軸に割り当てる
        // velocity.z = Input.GetAxis("Vertical");
        
        // Heightオブジェクトの向きを従って移動
        velocity += cameraYRot.right * Input.GetAxis("Horizontal");
        velocity += cameraYRot.forward * Input.GetAxis("Vertical");
        
        // 単位ベクトルにする
        velocity.Normalize();
        
        // 速度を乗算する
        velocity *= speed;
    }

    // （省略）
}
```

`cameraRotY` はカメラが Y 軸まわるオブジェクトなので、「Height」にして、実行してみてください。

### Timmyの向きを進行方向に合わせる

せっかくなので、Timmyが移動中に走っている向きに合わせて、回転しましょう。すでに「forward」を学んだので利用できる。Timmyの前方（`transform.forward`）は速度ベクトルと同じ。ただし、向きを変えるのは、**<span style="color: rgb(186, 55, 42);">入力がある時だけ。</span>**

上記の `Update()` は以下のように変わる：

```c#
private void Update()
{
    // 何も入力がない前提で、速度をゼロにする
    velocity = Vector3.zero;
    
    // Heightオブジェクトの向きを従って移動
    velocity += cameraYRot.right * Input.GetAxis("Horizontal");
    velocity += cameraYRot.forward * Input.GetAxis("Vertical");
    
    // 入力あれば、速度ベクトルはゼロではないはず
    if (velocity != Vector3.zero)
    {
        // 単位ベクトルにする
        velocity.Normalize();
        
        // 前方の向きを変える
        transform.forward = velocity;
        
        // 速度を乗算する
        velocity *= speed;
    }
}
```