クォータニオンによるキャラクターの制御メモ
クォータニオンを勉強するために,クォータニオンを計算して実装していたけど Unity の関数を使ったほうがコードがきれいなので移行したほうがよさそう.なので,note にメモを残しました.
カメラから見た正面にキャラクターを移動させる
Unity からの入力は,Input.GetButton で取得している.このとき,入力の座標系をカメラ座標系と考えることでカメラから見た正面への入力となる.
カメラ座標系での入力方向を,ワールド座標系での方向に変更する必要がある.Unity のカメラは,クォータニオンの変数をもっているのでこれを利用する.Unity でのクォータニオンは,単位クォータニオンで,ベクトルの回転を表している.なので,カメラのクォータニオンと入力ベクトルの積をとることでワールド座標系から見た入力ベクトルがもとまる.
最終的に,正規化したこのベクトルと移動速度の積よりキャラクターの移動速度がもとまる.
Quaternion qc = Camera.main.transform.rotation;
qc.x = 0f; qc.z = 0f; // カメラの上下は無視
Vector3 charactorVel = qc * new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")).normalized * speed;
下の画像より,カメラの座標系では,入力ベクトルは,カメラの z 軸方向だがワールド座標系では,z 軸ではないことがわかる.
というのが, Unity では関数でできる.
Vector3 charactorVel = Quaternion.AngleAxis(Camera.main.transform.eulerAngles.y, Vector3.up) * new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")).normalized * speed;
キャラクターを進行方向に向ける
キャラクターの初期姿勢は,ワールド座標系なので正面は vector3.forward (青矢印)で表される.これと向かせたい進行方向のベクトル(橙矢印)で外積をとる.これで得たベクトル(緑矢印)がキャラクターの正面方向ベクトルを進行方向ベクトルに回転させる回転軸になる.また,なす角より回転角がもとまるので,回転軸と回転角より回転行列がもとまる.
初期姿勢がワールド座標系なので,この回転行列が新たなキャラクターの姿勢になる.
Vector3 cross = Vector3.Cross(vector3.forward, charactorVel).normalized;
float angle = Vector3.Angle (vector3.forward, charactorVel);
rb.transform.rotation = Quaternion.AngleAxis(angle, cross);
というのが,Unity では関数でできる.
rb.transform.rotation = Quaternion.LookRotation(charactorVel, Vector3.up);
この記事が気に入ったらサポートをしてみませんか?