Unityの物理演算のHinge Jointが色々と使えそうだったので、使い方をメモしました。
1つの軸でRigidbodyを固定するだけでなくスクリプトなしで自動的に動かすこともできるので、扉・プロペラ・回転する床や壁・敵Mobの身体のパーツまでいろいろ活用できそうです。
物理演算とJoint全般に関する記事はこちら↓
もくじ
基本的な使い方
Rigidbodyのついているオブジェクト同士で使います。どちらかを親・もう一方を子と考えた場合の子の方のオブジェクトにHinge Jointコンポーネントをつけます。
Hinge JointのConnected Bodyに親側のオブジェクトを指定することで結合されます。
ヒエラルキーでの(Transformの)親子関係にはしないでおきます。
基本のパラメーター
Anchorは回転軸の中心になる座標で、子から見たローカル座標となります。
Axisは回転軸です。
Connected Anchorは親から見てどの位置に接続されているのか?という座標で、親からの相対的な座標にします。通常は親の中心になりますが、Auto Configure Connected Anchorのチェックを外せば任意の値に設定できます。

回転させる際の注意点
Hinge Jointを回転させる際、親側(Connected Body)のオブジェクトが回転するようにしていると回転の力が吸われるような感じでうまく動かなくなってしまうことがあります。
親の回転を制限するか、Massの設定を調整して子の回転が親に影響を与えにくいようにする必要があります。
回転の範囲制限
Hinge Jointは回転させる角度の範囲に制限をつけることもできます。ドアとかの設定で使えそうです。
パラメーターのUse Limitsにチェックを入れてからLimitsのMinとMaxを指定すればOKです。
値で指定するのが難しければ、Edit Angular Limitsを押すと画面上で変更することができるようになります。

画面に表示されるつまみを動かして調整します。

Spring
SpringはHinge Jointの特殊な機能です。
ドアなどで固定しないと勝手に閉まるものがありますが、ああいう感じで外からの力がかからなくなった時に指定の角度まで自動回転してくれる機能です。
使用するにはパラメーターのUse Springにチェックを入れ、Spring / Damper / Target Positionの3つのパラメーターを設定します。
パラメーターの調整がちょっと難しかったので、気になったところをメモしていきます。
RigidbodyのMass
これが重めだと止まる時にバウンドっぽい動きが発生しやすくなります。
バウンドっぽい動きをさせたくない場合はDamperの値で抑えることができますが、Massを軽くしても問題ないなら軽めにしてしまった方が扱いやすい気がします。
SpringとDamperの値設定
Springが加速度のようなもの、Damperがブレーキのようなものと考えるとよさそうです。
Springに対してDamperが低すぎるとバウンドが強くなります。
設定したいSpringの値に対してちょうどいい感じでDamperを設定するのが難しいですが、何度も試してみて値を決めるのがよさそうです。
Target Position
Positionという名前のパラメーターですが、実際は角度です。
Target Positionを90に指定している場合、y軸の角度が90度になるまで回転して止まるという感じです。
「扉が閉まる位置」みたいなイメージなのかもしれません。
Connected Bodyの回転
親側(Connected Body)のオブジェクトを回転できるようにしていると、Springの回転の力が吸われるような感じで途中で止まってしまうことがあります。
親側はFreeze Rotationをオンにするか、MassやSpring・Damperの値を調整してうまくいくまで頑張る必要があります…。
Springの特殊な使い方
Springは常時オンにしておくこともできますが、Use Springをfalseにすることで一時的にオフにすることもできます。
またTarget Positionもスクリプトから変更することができるので、パタパタする動きを繰り返すオブジェクトを作るのなどに使えそうです。
なおSpring / Damper / Target Positionをスクリプトから変更するには少し注意点があります。
この3つはJointSpringという構造体になっていて、hinge.spring.spring = 150.0f; みたいな記述では値を変更できません。
新しくJointSpringを宣言してからSpringとDamperとTarget Positionの値をすべて指定し、hinge.springにこのJointSpringを指定します。
var hinge = GetComponent<HingeJoint>();
var spring = new JointSpring();
spring.spring = 150.0f;
spring.damper = 40.0f;
spring.targetPosition = 90.0f;
hinge.spring = spring;
Motor
こちらもSpringと同じくHinge Jointの特殊な機能です。
名前のとおり自動でオブジェクトを回転させます。回転する床などをスクリプトからAddForceせずに作ることができます。
※SpringとMotorは同時に使うことができないとのことなので、必要な方だけtrueにします。
使い方もSpringと同様で、Use Motorにチェックを入れてTarget Velocity / Force / Free Spinを設定します。
こちらもそれぞれについて見ていこうと思います。
Target Velocity
この速度に達するまで加速・減速する値です。
ゲーム開始時はRigidbodyのAnguler Velocityが0なので必ず停止状態からの加速で始まります。
最初から回転させておきたい場合がなかなか難しく、Start()でRigidbody.angularVelocityを指定したとしても等速で回転し続けている感じにするのは難しいようです…。
(そもそもスクリプトから指定するなら毎フレームRigidbody.angularVelocityを指定した方がよさそうな気がします)
Force
速度がTarget Velocityになるまで加えられる力です。強ければTarget Velocityに達するのが早くなります。
現在の速度がTarget Velocityより遅い時はアクセル、早い時はブレーキになるようです。
Free Spin
これをtrueにすると、現在の速度がTarget Velocityより早い時にForceがブレーキにはならず自然に減速するようになります。
Connected Bodyの回転
こちらもSpringと同様で親に回転の力が吸われることがあるので注意が必要です…。継続して回転の力がかかるので、「気付いたら親側のオブジェクトがゆっくり回転していた」みたいなことになります。
Motorをスクリプトから変更
こちらもSpringと同様にスクリプトから変更することができます。
MotorはJointMotorという構造体です。変更方法はJointSpringと同様です。
まとめ
Animationを作ったりスクリプトから個別の挙動を作ったりしなくてもオブジェクトを動かせるので、動くステージを作る際などとても便利に使えそうです!
一方で動いているところは「いかにも物理演算だなぁ…」という感じで、予測不能な加減速・角度などになってしまうこともあります。
色々テストしてみながらゲームの仕様上問題ない動きになるよう調整する必要がありそうです。