UnityのSpring Jointを使う

# はじめに

Unityで、バネを使ったミニゲームっぽいものを学生さんと作りたいので、その基礎となるSpring Jointの勉強をしてます。このトピック、日本語のサイトで詳細な説明のあるものが少ないので、自分でまとめてみました。私自身、それほど良く理解してないので、間違いがあるかもしれません。何かありましたら、ご指摘頂ければ嬉しいです。


# Spring Jointの設定の仕方

とりあえず、Cubeを上下に二つ作る。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/5818b419-29d9-3dc9-a397-009f6bc83f9c.png)

上のCubeのPositionは(0,0,0)、下のCubeのPositionは(0,-5,0)に設定する。


![image](https://qiita-image-store.s3.amazonaws.com/0/58503/0a7f666f-ba22-0443-a13a-c02f8275b5c4.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/aebc3415-89ce-88a6-cc65-52348db1378e.png)



どちらのCubeにもRigidbodyコンポーネントをつける。

上のキューブは固定したいので、Use Gravityをオフにして、Constraintsを全てチェックする。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/23c57814-95a3-3d78-50d2-44cf324b0717.png)

下のキューブはMassを0.001にする（要するに、出来るだけ軽くする）

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/a8a7b558-8f0b-f9aa-cd20-53b658d3c9c7.png)



下のキューブにSpring Jointコンポーネントをつける。Connected bodyには上のキューブ("Cube")を設定。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/843cca5f-e100-198d-bcfb-3ebd3a7484ef.png)


ここで、下のキューブの上の面を見ると、茶色いポチがある。これがAnchor

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/271b80e0-b505-1fbb-dc91-30b5efb70f37.png)

Spring Jointコンポーネントで「Anchor X 0 Y 0.5 Z 0」というのは、Anchorが、Spring Jointコンポーネントがアタッチされているゲームオブジェクトの中心から、Y 0.5だけ上方向に離れている、ということ（ゲームコンポーネントのScaleが1以外の時は、それを掛け算する）。

その下のConnected Anchorは、ばねのもう一方（今回なら、上のキューブ）が繋がる場所。Auto　Configure Connectedで設定することも可能だが、今回はこのチェックを外して Y -0.5を入力する。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/96a8db77-67c4-e422-7c8b-ad82f4a4ee29.png)

すると、上のキューブの底面にアンカーがくっついている。これがConnected Anchor。　Y -0.5というのは、上のキューブの中心から0.5下ということ（ゲームコンポーネントのScaleが1以外の時は、それを掛け算する）。
。

# 重りをバネにぶら下げてみると

この状態で実行すると、下のキューブが上のキューブにくっついてしまう。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/1f85f3ec-abfb-a843-818b-73dfb98cd920.png)

これは、Spring JointコンポーネントのMax Distanceを調整していないため。Max Distanceを3にすると、下のキューブは Y -4のあたりで止まる。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/37c03a54-bdde-b0f3-3467-b8c21fc35bea.png)

これは、アンカー同士の距離でいうと3にあたる（上のキューブのアンカーは、中心より0.5下、下のキューブのアンカーは中心より0.5上であったことを思い出す）。このように、**Max Distanceで重りに重さがない時にばねをぶら下げた場合の距離を調整できる**。

# 重りをバネの上に置いた場合

それでは、今度は下ではなく上のキューブを動かす。下のキューブはRigidbodyのConstraintを設定して全く動かないようにし、Use Gravityもオフにする。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/aa03c663-f80f-8c30-f57b-53f020b4c92b.png)

逆に、上のキューブはmass 0.001, Use Gravityをチェック、ConstraintsのFreeze Position Yだけをアンチェックする。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/c27e347a-4494-28c2-49b1-8c8168b917f5.png)

この状態で、先ほどと同じようにSpring JointコンポーネントのMax Distanceを3にして実行すると、上のキューブは下につきぬけて Y = -7で止まる。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/04b6b016-38e8-c09c-217d-ae4af1e7ac51.png)

キューブ間の距離は２だが、はじめに上にあったキューブのアンカーは、中心より0.5下、下にあったキューブのアンカーは中心より0.5上であったことを思い出すと、アンカー間の距離は3。つまり、先ほどと同じように、アンカーの距離はmax distanceの設定と同じになっている。

## 突き抜けないようにする

突き抜けるのは困るので、それを防ぐためにSpring Jointのmin distanceも設定する。たとえば、min distanceを1にすれば、

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/bb49021b-5c78-3a5d-f5d9-1531581e91d1.png)

実行した時、上のキューブは、下のキューブの上で止まる。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/137b9a5b-158e-63a6-9ee7-33c5d7b6dea1.png)

上のキューブの位置はY -3、つまりキューブ間の距離は2だが、アンカー間の距離はmin distanceで決めた1になっている。

このように、Spring Jointコンポーネントの**min distanceは、ばねが縮む方向に力がかかる時の長さを決めるのに使える。**

# つづき

長くなったので、[こちらの記事](http://qiita.com/yanosen_jp/items/949eae56f2fcf6c8a0b0)に続きを書きました。min distanceが変わると、ばねの性質がどう変わるかを詳しく検証しています。よろしければ、こちらもご覧ください。