親子構造を持つオブジェクトの回転が思った通りにならなかったのは慣性テンソルが原因だった。
状況
- 空の親オブジェクトの子要素に2つのcubeが入っている
- 上のcubeのpositionは(-0.5, 1, 0)
- 下のcubeのpositionは(0, 0, 0)
- cubeにはBox Colliderをアタッチ
- 空の親オブジェクトにRigidbodyをアタッチ
- RigidbodyのConstraintsでFreeze Rotation以外チェックボックスをオンに
- ローカルのVector3.upでだけ回転させたかった(コマのようなイメージ)
この状況下でRigidbodyとColliderをもつ他のオブジェクトを衝突させてもコマのような回転にならなかった。
原因
結果としては慣性テンソルの回転角度が原因だった。
Unityでは慣性テンソルの回転角度がRigidbodyにアタッチされているすべてのColliderから自動的に計算されるのだが、このおかげでイメージ通りに回転しなかった。
上記の状況ではこの値がEulerAnglesで(0, 0, 26.6)になっていた。
実際の物理挙動的にはこちらが正しいのだが、イメージ通りに動かすためにこの値を書き換えることで期待する回転運動を得ることができた。
修正
InertiaTensor.cs
private void ResetTensor()
{
var rigid = transform.GetComponent<Rigidbody>();
rigid.inertiaTensorRotation = Quaternion.identity;
}
Quaternion.identity
とすることで回転していない状態を慣性テンソルの回転角度とした。
参考
ニュートンの第2法則
直線運動 質量 × 加速度 = 力
回転の運動方程式
回転運動 慣性モーメント × 角加速度 = トルク