次は物体の反発を Unity を使って再現してみましょう。
演習を行う前に新しいシーンを作り、球と床を作成します。
アセットフォルダの Scenes フォルダの中にシーンを新規作成し、シーン名を「HANPATU Scene」にする。背景色は任意で構わない
新規作成したシーンへ移動する
ヒエラルキー右クリック → 3D Object → Sphere で球を新規作成し、名前を「TAMA」、Position を (0,5,0)にする
TAMA に Rigidbody をアタッチする
ヒエラルキー右クリック → 3D Object → Quad で平面を新規作成し、名前を「YUKA」、Position を (0,-2,0)、 Rotation を (90,0,0)、Scale を (10,10,1) にする
この時の状況が図1になります。
この状態で実行ボタンを押すと全く反発せずにそのまま YUKA に TAMA がくっつきます。
図1. 床を用意
では反発の設定をしていきます。
反発を行うためには「物理マテリアル(Physic Material)」というアセットをアセットフォルダの中に以下の手順で作ります。
※ 色とテクスチャの設定で使った「マテリアル」とは違う種類のアセットなので注意して下さい
アセットフォルダの空いている部分を右クリックしてメニューを表示し、Create → Folder でフォルダを新規作成し、「Materials」という名前に変更する
Materials フォルダの中に入り、空いている部分を右クリックしてメニューを表示し、Create → Physic Material を選ぶ ※ Material の方を選ばないよう注意
Materials フォルダ内に「New Physic Material」というアセットが出来るので「TAMA Physic Material」に名前を変更する
同様に Materials フォルダ内に「YUKA Physic Material」も作成する
では反発の設定をしていきます。
TAMA Physic Material をクリックしてインスペクタを表示する
Bounciness を 0.98 にする
TAMA Physic Material をドラッグしてヒエラルキーの TAMA の上にドロップする
TAMA のインスペクタを開き、 Sphere Collider の中に TAMA Physic Material と表示されているのを確認する
同様に YUKA Physic Material の Bounciness も 0.98 にし、YUKA にドラッグ&ドロップし、YUKA のインスペクタを開いて確認する
ここまで出来たら早速実行ボタンを押してみましょう。
TAMA が跳ね返ってだいたい元の位置まで戻る事が分かります。
※ 計算誤差があるので完全に同じ位置までは戻りません
次に「TAMA Physic Material」と「YUKA Physic Material」の Bounciness を両方とも 0.69 にして実行して下さい。
すると反発力が落ちて跳ね返るたびに元の半分の高さまでしか戻らなくなります。
最後に「TAMA Physic Material」と「YUKA Physic Material」の Bounciness を両方とも 0 にして実行して下さい。
すると全く反発しなくなります。
この様に、Bounciness の値が 1 に近いと反発力が強くなり、逆に 0 に近づくにつれて反発力が落ちていきます。
ここから先は少し難しい話なので分からなければ飛ばしても結構です。
ただし Unity の物理演算機能を使いこなすためには大事な知識ですので興味のある人は是非トライして下さい。
Physic Material の Bounciness について詳しく説明する前に現実世界の反発係数についておさらいしておきます。
TAMA と YUKA がぶつかった時に TAMA の速度が $v1$ から $v1'$ 、YUKA の速度が $v2$ から $v2'$ に変わったとしたら反発係数は
\[ e = \frac{ |v1' - v2'| }{ |v1 - v2| } \]となりますが、今回のシチュエーションでは YUKA は静止している( $v2 = v2' = 0$) ので反発係数は
\[ e = \frac{ |v1'| }{ |v1| } \]
となります。
ここで $e = 1$ の状況を完全弾性衝突と呼んで、 TAMA の反発後の速度は不変で方向だけ変わります(つまり $v1' = -v1$ )。
逆に $e = 0$ の状況を完全非弾性衝突と呼んで、 TAMA の反発後の速度は $v1' = 0$ となります。
また $e$ が 1 より大きい場合は跳ね返った後の速度の方が早くなります。
以上の話を踏まえて Bounciness の話に戻ります。
結論から言うと
Bounciness ≒ 反発係数
です。
※ 完全にイコールでない理由についてはこれから順を追って説明します
まず TAMA と YUKA がぶつかった時に使われる Bounciness の値はデフォルトでは TAMA と YUKA の Bounciness の平均値になります。
今回は両方とも同じ値を使う様にしていたので Bounciness の平均値も同じになりますが、もし平均値を使いたくない場合は Physic Material の Bounce Combine を Average(平均) から他の設定に変えます。
例えば自分のキャラクターには反発を設定せずに床とか壁とかに反発の設定を任せたい時があります(金属の床とかマットレスとかトランポリンとか色々な状況が考えられますね)。
その場合は自分のキャラクターの Bounciness を 0、Bounce Combine を Maximum にします。
ここでは Bounce Combine についてこれ以上詳しく説明しませんので、興味のある人は調べてみて下さい。
次に、Unity の物理演算エンジンは反発する時に若干運動エネルギーを加えます(計算誤差を補正するため?)。
そのため Bounciness の値を 1 にすると反発後の速度の方が若干早くなります。
従って Bounciness の値は現実の反発係数よりも若干小さめの値にする必要があります(理論的にどの位小さくすれば良いかは未調査です)。
上の方で Bounciness の値を 0.98 にしていた理由はそのためです。
この様な Unity 特有の癖にさえ気をつければ後は普通の反発係数と同様に計算できます。
例えば反発後に戻る高さを元の 1/2 にしたい場合は Bounciness の値をいくつにすればよいか考えてみましょう。
戻る高さが半分になるということは反発時に位置エネルギーの半分が失われるということを意味します。
つまり衝突時に運動エネルギーが半分になるということなので、TAMA の重さを $m$ 、反発前の速度を $v1$ 、反発後の速度を $v1'$ とすると
という式が成り立ちます。
これを解くと
なので反発係数は
\[ e = \frac{|v1'|}{|v1|} = \frac{1}{\sqrt{2}} = 0.707106781\cdots \]
となります。
ただし Bounciness の値は現実の反発係数よりも若干小さめにしないと駄目なので上の例では Bounciness = 0.69 としました。