Rigidbody.constrainsですが 、スクリプトから操作するときに指定できるものがあらかじめEnum型として決まっています。
None | 制限なし |
FreezePositionX | X 軸の移動をさせない |
FreezePositionY | Y 軸の移動をさせない |
FreezePositionZ | Z 軸の移動をさせない |
FreezeRotationX | X 軸の回転をさせない |
FreezeRotationY | Y 軸の回転をさせない |
FreezeRotationZ | Z 軸の回転をさせない |
FreezePosition | 移動させない |
FreezeRotation | 回転させない |
FreezeAll | 移動と回転をさせない |
上の一覧のとおり、Rigidbody.constrainsには、特定の軸だけを解放するという値は用意されていません。
一方で、特定の軸だけは解放したい、という場面は結構あります。ところが、 「z軸の回転だけは解放したい」といった場合に、 以下のようなコードを書いてしまうとうまくいきません。
private void UnlockRotationAxisZ()
{
rigidbody.constraints = RigidbodyConstraints.FreezePosition;
rigidbody.constraints = RigidbodyConstraints.FreezeRotationX;
rigidbody.constraints = RigidbodyConstraints.FreezeRotationY;
}
このコードの結果は、以下のようになります。
RigidbodyConstraints.FreezeRotationYは、Y軸の回転だけをロックした状態、という意味なのです。ほかのコンストレインツがどうなっていようが、お構いなしに上書きしてしまいます。
本来は、こうなってほしいはずです。
こういう状態にするには以下のようにコードを書かなければいけません。
private void UnlockRotationAxisZ()
{
rigidbody.constraints = RigidbodyConstraints.FreezePosition
| RigidbodyConstraints.FreezeRotationX
| RigidbodyConstraints.FreezeRotationY;
}
見慣れない演算子がでてきたかもしれません。|はビット演算子の一種です。
以上のように、特定の軸だけを解放したコンストレインツを設定するには、すこし注意が必要です。
上のビット演算子は、公式のドキュメントのサンプルコードには登場するのですが、特に注意書きがあるわけでもないので、見逃してしまう人も多いでしょう。
自分もすこしハマってしまったので、同じような状況に出くわした人の助けになれば幸いです。