【Unity】Rigidbodyの各パラメータは何に使われているの?【解説】

【Unity】Rigidbodyの各パラメータは何に使われているの?【解説】

Unityで物理エンジンを使う際に必要になるRigidbody。

Unityを触った人で、このコンポーネントを使ったことが無い人は殆どいないんじゃないかくらいのレベルで大事なコンポーネントです。

今回はRigidbodyの各パラメータについての説明と、どんな場面で使えるか、基本の部分をご紹介。

基本とはいうものの、スクロールバーを見てもらえば分かる通り、結構がっつり解説してます。

 

環境

macOS 10.13 High Sierra

Unity2018.1.0f2

4月末にUnity2018が出てたので早速使ってみました。

Rigidbodyとは

Rigidbodyは、Unity世界のオブジェクトにアタッチするコンポーネントで、これによって物理挙動を可能にします。

詳細については公式マニュアルを見てもらうといいかな。

物理的な運動を制御するだけあって、物体の質量だったり、空気抵抗だったりのパラメータが用意されています。

外部から力を加えて運動させるときにこうしたパラメータが使われます。例えば質量を大きくすれば、より大きな力じゃないと動かないようになったり。

この辺は高校物理の知識でも直感的に分かるようになっています。やってて良かった高校物理。

物理を履修してなかったぜ!! という人は、公式とかは覚えなくても『慣性の法則』とか『空気抵抗』といった単語の意味を言葉で拾っておくだけでも、ゲーム作りに活かせます。

Rigidbodyのアタッチ

Rigidbodyは[Add Component] -> [Physics] -> [Rigidbody]からアタッチすることができます。検索窓で『Rigidbody』と入力してもOK。

Rigidbodyのアタッチ
Rigidbodyのアタッチ

 

Rigidbodyのパラメータについて

Rigidbodyはなかなかパラメータの多いコンポーネントなので、何を変えられるのかを把握するのは大変かも。

Rigidbodyのパラメータ
Rigidbodyのパラメータ

 

上から順にざっくりと解説します。

Mass(質量)

物体の質量を設定するのがMassです。Unityのマニュアルによると単位はkg。

この値が小さければ、力を与えられたときに加速度が大きくなります。つまり動かしやすい物体ですね。

逆に大きくなれば、力を与えられたときの加速度は小さくなります。こっちは逆に動かしにくい物体になります。

物理に慣れてる人向けに言えば、ニュートンの運動方程式ma=Fを思い出せばOK。力Fが一定なら、加速度aは質量mに反比例します。

物理に慣れてない人向けに言えば、重いものを持ち上げようとしたときのことを思い出してもらえればいいかな。結構力を入れないと、重い物って持ち上がらないですよね。あの感じです。

最小値は1e-07(1.0 * 10-7)で、0にはなりません。もし負の値になったら反重力物質かな。

最大値は1e+09(1.0 * 109)です。100万トンまで表現できるんですね。Wikipediaによれば世界一重い船(ノック・ネヴィス)の最大積載量が65万トンらしいので、それよりもう少し重い物までなら設定できます。

ただまぁ設定ができるとはいえマニュアルでは、

mass が大きいと、物理演算が不安定になります。

と書かれているため、あまり質量を大きくせず、他の物体と同じようなオーダーに設定しておくのが望ましいですね。

Drag(抵抗)

続いては抵抗です。

地上で転がる時だったり、落下の時だったり、斜方投射の時だったりと、あらゆる運動に抵抗がかかります。電気的な抵抗とは別ね。

最小値は0で、初期値も0になっています。0の場合は抵抗なしで運動します。

最大値はInfinityです。無限大だと即停止レベル。というか生半可な力を加えても動きません。Dragフィールドに[inf]と入れるとInfinityと補完してくれます。

水中など、あるエリアに入ったときにこの値を切り替えるといいかも。水中に入ったことはColliderのOnTriggerEnterを使えば検知できるので、そのときにDragの値を大きくすれば、水中での抵抗を受ける表現が可能です。

あとは公式のリファレンスにもあるように、パラシュートを開いたらDragの値を大きくするとか。

 

AngularDrag(回転の抵抗)

こちらはオブジェクトの回転にかかる抵抗です。

例えばAddForceを使って斜方投射のようにボールを打ち上げた時、最初に空中に飛び出した時にはボールは回転していないので、AngularDragによる回転運動の減衰は行われません。

このボールは地面に衝突したときに回転を始めるので、そこから回転運動の減衰が始まり、いずれは停止するようになります。

物理特性マテリアルを使うと摩擦力の設定を行うことができますが、ボールのような物体は地面を転がっていても思うように摩擦力が働きません。そんなときにこのAngularDragを大きめに設定しておけば、地面を転がっているときに摩擦力が働いているように表現できます。

最小値は0です。0の場合は減衰することなく回転し続けます。

最大値はInfinityです。無限大でも、上記の斜方投射で接地したときには少し転がります。

UseGravity(重力の使用)

これは言葉から読み取りやすいパラメータですね。重力の影響を受けるかどうかを決めます。

Unity世界では重力が働いており、このパラメータがtrueになっているRigidbodyを持つオブジェクトは重力の影響を受けます。

重力の大きさを設定するには、物理演算マネージャーを開きます。メニューバーから[Project Settings] -> [Physics]を選択。

PhysicsManagerを開く
PhysicsManagerを開く

 

『Inspector』ウィンドウにはPhysicsManager(物理演算マネージャー)が表示されます。この一番上にある項目が重力を決めるGravityです。デフォルトではYが-9.81になっており、現実の重力加速度と同程度となっています。

PhysicsManagerウィンドウ
PhysicsManagerウィンドウ

 

Use Gravityがtrueの場合には、そのRigidbodyは重力の影響を受けて落下していきます。

逆にfalseの場合は、重力の影響を受けないため、その他の力が加わらない限りは落下しません。

無重力空間のオブジェクトを表現するのに便利なので、宇宙空間を漂う岩とかスペースデブリなどを使う場合はチェックを外すのがいいですね。

IsKinematic(物理演算の影響を受けるかどうか)

IsKinematicがtrueだと物理演算の影響を受けず、falseだと影響を受けます。

問題児のIsKinematicさん。Unity初心者が「えっ何これ……怖いから触らんとこ」となる要因の一つです。

Kinematic(キネマティック)って言葉がもう馴染みない感じですし。直訳すると『運動学的な』となる形容詞。そもそも『運動学』自体が日本語でもそんなに触れる機会もないような……。

運動学とは物理における力学の一分野で、物体の運動に関して力の詳細にまでは触れず、位置の移動やその時間変化など、数学的に記述する分野のこと。

ポイントは、力の詳細に触れない点。

Unity的に考えると、Rigidbodyに与えられる力(AddForceやGravityなど)の影響を受けないってことなんです。

IsKinematicをtrueにした物体は、アニメーションやスクリプトなどからtransformをいじって位置を変えたり、回転させたりして動かす必要があります。

IsKinematicがtrueで、スクリプトから位置を動かしている物体であっても、他のRigidbodyに衝突すると相手に影響を及ぼします。

3Dモデルを作って、それをアニメーションさせている場合にはIsKinematicをtrueにした方がいいですね。衝突が起こることを考えればmassとかも使いたいので、 Rigidbodyは付けたまま、IsKinematicで物理演算の影響を外す感じ。

 

Interpolate(補間)

InterpolateはFixedUpdateによる物理処理を滑らかにするための設定です。Interpolateの日本語訳は「付け加える」とか「差し挟む」といった感じ。

Unity2017.4までは、FixedUpdateはデフォルトで1秒間に50回の更新となっています。Unity2018.1からは、デフォルトだとFixedUpdateが1秒間に60回呼ばれるようになりました。

対して、画面の描画に関わるUpdate関数が呼ばれる回数は変動します。

デフォルトだとPC向けゲームでは可能な限りFPSが上昇しますし、スマホ向けゲームでは30FPSになっていたりと、FixedUpdateが呼ばれるタイミングと必ずしも一致しないんです。

これによって何が起きるのかと言えば、物理演算と描画タイミングが一致しないため、本来いて欲しい位置にオブジェクトが間に合わず、結果としてカクツキとなって現れます。マニュアルでは『痙攣しているような見た目』と表現されていました。怖い。

これを防いでくれるのがInterpolateです。

デフォルトでは『None』となっており、補間が行われない状態です。

『Interpolate』を選択すると、補間が行われ、描画がスムーズになります。補間は直前フレームの速度を使って計算します。こちらは過去の実績に基づいて位置を算出する方法ですね。

『Extrapolate』を選択した場合も補間が行われますが、こちらは現在の速度から次フレームの位置を予測して補間を行います。『Interpolate』とは逆に未来予測で位置を算出します。

マニュアルやUnityフォーラムの上記の記事を参考にすると、『Interpolate』では過去の位置に基づいて描画時の補間を行うので、変な位置になることは少ないようです。しかし計算のコストがあるため、どちらかと言えば重い処理になります。

『Extrapolate』では現在の速度を見て予測を行いますが、急激に速度が変化した場合などには、おかしな位置が算出される可能性もあります。処理の重さで言えば『Interpolate』より軽いようです。

この設定はプレイヤーオブジェクトなど、カメラで追いかけるメインのオブジェクトに使用するのが望ましいとのこと。

Collision Detection(衝突の検知)

Collision Detectionは衝突の検知に関する設定です。

高速で運動する物体などは、フレーム更新の隙間を縫って壁をすり抜けてしまうことがあるんです。

これは、衝突検知のタイミングが離散的であるため。デフォルトでは衝突検知のモードがDiscrete(離散の)になっているので、その間に物体を通り過ぎれば衝突がなかったことに。

これが……これがトンネル効果……!!

ゲームの世界とはいえ、トンネル効果がぽんぽん発生しても困るので、高速で動く物体でもちゃんと衝突したことを検知するために設定するのがこのフィールド。

設定値は『Discrete』、『Continuous』、『ContinuousDynamic』の3つ。

『Discrete』は上でも触れましたが、離散的に衝突を検知します。FixedUpdateが呼ばれたタイミングで衝突を確認するため、そのときにColliderが重なっていないのであれば衝突したと見なされません。

デフォルトではこれが選択されています。確認の回数は比較的少なく高速なので、パフォーマンスの観点から言えば、なるべくこれを選んでおきたいところです。

『Continuous』は、このRigidbodyを持ったオブジェクトの進路上に、Rigidbodyを持っておらず、かつColliderを持つオブジェクトがあれば、FixedUpdateの間であっても連続的に衝突を検知します。Continuousはそのまま「連続的に」といった意味。

Rigidbodyを持っていないけど、衝突はしてほしいオブジェクト(例えば壁など)との衝突をちゃんと検知したいときにはこれを選びます。

衝突を検知してほしい相手がRigidbodyを持っている場合は、下の『ContinuousDynamic』を使います。

『ContinuousDynamic』は『Continuous』のケースに加えて、相手がRigidbodyを持っていても、相手のCollision Detectionが『Continuous』または『ContinuousDynamic』であれば連続的に衝突を検知してくれます。衝突検知の精度ではこれが一番。

ただ、パフォーマンス面では3つの中で一番重い処理となります。

なおマニュアルによると、『Continuous』および『ContinuousDynamic』で連続的に衝突を検知できるのは、Sphereコライダー、Capsuleコライダー、Boxコライダーのみだそうです。

MeshコライダーやTerrainコライダーなどは対象外っぽい。複雑なメッシュだと流石にPCが悲鳴をあげますもんね。

 

Constraints(制限)

Constraintsは制限を意味する言葉で、チェックを入れた軸に関する移動や回転を制限できます。

例えばX-Y平面だけでゲームを動かしたいときには、Z軸方向に移動させたくない場合があります。そんなときにこのConstraintsでFreeze PositionのZ軸にチェックを入れれば、Z軸方向に運動しなくなります。

衝突で弾かれたときにも有効なので、思わぬ方向に飛んで行かないようにこの設定を入れておくといいかも。

『Freeze Position』は位置の固定です。指定した軸方向の運動を制限することができます。

『Freeze Rotation』は回転の固定です。指定した軸を中心とする回転を制限できます。

見た目は3Dのオブジェクトだけど、移動できる方向は2Dのアクションゲームで使えるかな。

まとめ

基本的な話と言いつつ結構がっつりめな解説でした。

イメージしやすいパラメータもあれば、なかなかイメージしにくいパラメータもあるので、実際に動かしてみるのが一番かも。

この記事でも日本語訳を付け加えてみたりと、なるべくイメージできるようにはしてみました。

公式マニュアルを見たり、自分で手を動かしたり、他の人の解説を読んだりとしているうちに動きが掴めてきます。

大丈夫! Rigidbody、コワクナイヨ。ホントダヨ。

アセット作ってます!

CTA-IMAGE

Unityでの開発に役立つアセットを作っています。

3DダンジョンRPGを開発するスピードを200%加速するAssetや、ファンタジーRPGのダンジョンを彩るパーツを取り揃えています。

特に3DダンジョンRPGのゲームを1から作るのは結構時間がかかります。ダンジョン部分の作成はこうしたアセットを使って、開発をブーストさせてみませんか?