Timmyがカメラに相対的に移動する
これでカメラが自由に回転できるようになったが、今度何かおかしい現象が発生。
カメラが主人公の後ろにある場合は、何とか正しく動きますが、真横、または正面から見ると入力する、主人公の動きが変に感じる。なぜなら、キャラクターがカメラの位置を関係なく、世界のXZ軸に沿って動くので、カメラの向きが変わったら、おかしく感じる。
この問題を解決するには、世界に絶対的に動くのではなく、カメラの向きに合わせて相対的に移動すること。
|
|
|
|
この場合は、カメラ前方(青い矢印)が世界のZ軸と並行になっているので、「W」キーを押すと、正しく移動する |
一方、Heightを回すと、カメラ前方の向きが変わり、「W」を押すと、世界に対して斜め(青い矢印の向き)に移動してほしい |
スクリプト
PlayerMove を編集し、世界のXZではなく、Heightの回転を従って移動させましょう。これには、Transform コンポネントの「forward」と「right」を使いましょう!
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)は速度ベクトルと同じ。ただし、向きを変えるのは、入力がある時だけ。
上記の Update() は以下のように変わる:
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;
}
}