Unityにおける回転処理に関する解説資料
回転のさせ方
Unityでは、以下のようにさまざまな回転方法があります。 具体的にその一部のプログラムを見ていきます。
1. transform.localEulerAngles で回転
//①
transform.localEulerAngles += new Vector3(0, inputX, 0) * yRotSpeed * Time.deltaTime;
解説
localEulerAnglesはローカル座標系での回転角度を表すVector3です。この方法は単純で直感的ですが、オイラー角を使っているため、ジンバルロック(特定の角度で回転軸が失われる問題)に注意が必 要です。- ジンバルロックは、オブジェクトが特定の角度に達すると正しく回転しなくなる問題で、複雑な回転処理には向いていません。
改善点
ジンバルロックを避けたい場合は、Quaternionを使って回転を処理する方法が一般的です。
2. Quaternion を使用した回転
//②
yRot += new Vector3(0, inputX * yRotSpeed * Time.deltaTime, 0);
transform.rotation = Quaternion.Euler(yRot); // ワールド座標での回転
解説
Quaternion.Eulerを使って、オイラー角(Vector3で指定された角度)をクォータニオンに変換し、回転を制御しています。Quaternionはジンバルロックの問題を回避するため、3次元回転の計算には適しています。transform.rotationはワールド座標系で回転を設定するため、オブジェクトがワールド空間での回転を維持します。
改善点
回転の処理において、Time.deltaTimeをかけて時間によるフレーム間の変動を考慮することが重要です。
3. Time.deltaTimeを直接使用してしまうケース
//③ 変な挙動になるはず
yRot += new Vector3(0, inputX, 0);
transform.rotation = Quaternion.Euler(yRot * Time.deltaTime * yRotSpeed);
解説
Time.deltaTimeを回転角度に直接乗算する方法は、バグを引き起こす原因となります。例えば、フレームレートが不安定な環境では、計算結果がばらつくため、意図しない角度の変動が発生します。- このコードでは、
Time.deltaTimeが異なる値になるたびに回転速度が不安定になるため、オブジェクトが不規則な速度で回転してしまいます。
修正案
Time.deltaTimeは角度変化の速度に適用するだけで、直接回転の変化量にかけるべきではありません。正しくは以下のようにすべきです。
yRot += new Vector3(0, inputX * yRotSpeed * Time.deltaTime, 0);
transform.rotation = Quaternion.Euler(yRot);
4. transform.Rotate メソッドを使った回転
//④
transform.Rotate(new Vector3(0, inputX, 0) * yRotSpeed * Time.deltaTime);
解説
transform.Rotateは、回転をローカル座標系またはワールド座標系で直接操作できるメソッドです。- デフォルトではローカル座標系での回転を行い、
Space.Worldを指定すればワールド座標で回転ができます。内部的にQuaternionを扱っているため、ジンバルロックの問題も回避できます。