【Unity徹底解説】Rigid body【使い方・インスペクター編】

<概要>

Rigidbodyとは

コンポーネントの一種です。
アタッチしたゲームオブジェクト が物理演算で挙動するようになります。
コライダーがついている子オブジェクトも挙動の影響を受けます。

単体のパターン

fall down

子オブジェクト有り(SphereはCubeの子)

fall down two

子オブジェクトがあると子オブジェクトを全て合わせて計算されます。

なお、コライダーがセットされていない子オブジェクトは考慮されないので注意してください。
↓Sphereのコライダーをオフにしている状態

fall down no collider

Transform操作と物理エンジン操作

Unityで物体を動かそうと思った時、次の2パターンになります。

Transform操作・・・位置情報を直接制御する方法(ただ移動するだけ)

・物理エンジン操作・・・物理演算でオブジェクトの位置を制御する方法(オブジェクトを動かした時周囲の状況により様々な計算が入る)

Rigidbodyをゲームオブジェクトにアタッチした場合、デフォルトでTransform操作でしか動かせなかったオブジェクトが、物理演算を用いた操作方法が可能になります。子オブジェクトも影響を受けます。物理演算で動いているオブジェクトをTransform操作することは可能ですが、Rigidbodyがついていないオブジェクトを物理演算挙動で動かすことはできません。(自作やフレームワークを使わない限り)

Unityで物理エンジン操作をする時の注意点

物理演算挙動で動作しているものがある状態で、物理演算に関連性があるオブジェクトのTransformの値を変えると再計算が行われる。

これめちゃくちゃ重要なので覚えておいてください。物理演算というのは非常に重い処理です。慎重に取り扱わないとゲームがカクカクになります。再計算が行われるということはさらに重くなるということです。

どういうことかというと↓の図は
・左がRigidbody有り
・右がRigidbody無し
で、両方にBoxColliderがついています。
BoxColliderは物理演算に関連性のあるコンポーネントです。

explain-rigidbody

この状態で無しのオブジェクトを動かすと、有りのオブジェクトに再計算が走ります。有りのオブジェクトが動かなくても二つが衝突しなくても再計算が走ります。これはそもそもオブジェクトの移動が瞬間移動であるので、再計算せざるをえないのです。オブジェクトの移動についてはこちらにまとめましたので、よくわからない方は参考にしてください。

オブジェクトの移動は瞬間移動なのですが、Transformの瞬間移動と物理演算での瞬間移動は違います。Transformは瞬間移動させるだけなのですが、物理演算は瞬間移動させる際にあれこれ計算してから瞬間移動させています。ある地点に物体を移動させようとした時、そこに何があるのか、どういった影響を受けるのか事前に計算して最終的に瞬間移動する位置を決めて移動させているわけです。そこに突然物理演算外から瞬間移動してくる物体があった場合、例えRigidbodyがついたオブジェクトが動いていなくても、外から瞬間移動してきた物体とぶつかっているかどうかわからないので再計算が走るわけです。

問題になる例をあげると、アクションゲームでキャラクターをRigidbodyで動かしたとます。そして、動く床をTransformで動かしたとします。この動く床を大量に配置した場合ゲームがカクカクになりやすいです。この「なりやすい」というのがミソでTransformで動いているものが1個で処理が少し重くなります。多少であれば大丈夫です。でも少しは重くなっているので、ゲーム中に配置すればするほどジワリジワリ重くなっていき、30FPSを切った瞬間カクカクになります。これのマズイところは初心者には原因の特定がしづらい点です。何故なら今までは普通に動いていたのですから。また、スマホやブラウザに移した瞬間カクカクになったりします。

対策としては
物理エンジンに関係するオブジェクトは物理演算による移動を行うようにする
です。

Transformの移動ではなくRigidbodyを通した移動を行うとよいでしょう。
ちなみにアニメーションによる移動はTransformの移動です。
Rigidbodyを通した移動はこちらのスクリプト編からどうぞ



<インスペクター>

inspector_rigidbody

・Mass・・・物体の質量を決めます(Kg単位)

・Drag・・・空気抵抗。0で抵抗無し。無限で動かなくなる

・Angular Drag・・・回転する際の空気抵抗。0で抵抗無し。無限にしても回転はする

・Use Gravity・・・オンで重力の影響を受けるようになる。落下速度はMassを調整しよう

・IsKinematic・・・オンで物理演算の影響を受けなくなる

・Interpolate・・・移動の際の補間方法を選ぶ

・CollisionDetection・・・コライダーの計算方法を選ぶ

・Constraits・・・オブジェクトの動きに制限を設ける

IsKinematicについて

Rigidbodyがついているオブジェクトが物理演算の影響を受けなくなります。これって意味あるの?って話なのですが、もちろんあります。例えばRigidbody概要の方で説明した処理が重くなる話ですが、物理的な動きをしない物を動かしたい時(例えば動く床等)RigidbodyをつけてIsKinematicをオンにすればTransform的な移動ではなく物理演算的な移動にする事ができます。また、物理演算で動いていたものを途中でTransform的な動きに切り替えたい時にオンにする使い方もできます。(特定のアクションの間は物理演算ではない挙動にしたい等)

Interpolateについて

移動の際の補間方法を選びます。物理演算を行う計算タイミングと画面に物体を描画するタイミングが違うので、オブジェクトの移動がガクガクします。このタイミングによるズレを考えて計算するよという事です。物理演算のタイミングはFixedUpdateで描画タイミングはUpdateです。

・None・・・補間を行わない

・Interpolate・・・直前フレームの速度を使って補間

・Extrapolate・・・現在の速度から次フレームの位置を予測して補間

補間をオンにすると当然重くなります。Interpolateの方が重いです。Extrapolateの方が軽いですが予測補間なので変な位置に描画されるリスクがあります。

使いどきは移動がガクガクする奴がいる時でしょうか。基本はNoneで大丈夫です。

CollisionDetectionについて

Unityの移動は瞬間移動である為、当たり判定のすり抜け等が起こります。これを防ぐ為に計算方法を選びます。Unityの移動が瞬間移動であるという話はこちらから

collision error

瞬間移動する前とした後の間にコライダーがあるとすり抜けてしまいます。

・Discrete
デフォルト設定です。瞬間移動した時に衝突しているかどうかをみます。

・Continuous
「Rigidbodyなしのコライダー」と「RigidbodyのContinuous Dynamicの設定がされているコライダー」に対して事前に計算を行なってから衝突しているかどうかをみます。その他のコライダーに対しては瞬間移動した時に衝突しているかどうかをみます。

・Continuous Dynamic
「RigidbodyのDiscreteが設定されているコライダー」のみ瞬間移動した時に衝突しているかどうかをみます。その他のコライダーは事前に計算を行なってから衝突しているかどうかをみます。

この時、瞬間移動した時に衝突しているかどうかをみる事を離散型衝突検知といい、事前に計算を行なって衝突しているかどうかをみる事を連続型衝突検知といいます。連続型衝突検知はものすごく複雑な計算を行なっているので、これにすると重くなります。

基本はDiscreteにしておき、当たり判定のすり抜け等がおきたら他2つの設定を検討してみると良いでしょう。

Constraitsについて

オブジェクトの動きに制限を設けます。

Freeze Position・・・位置情報を固定します。x,y,zのチェックした値が固定されます。つまりチェックした項目が動かなくなります。

Freeze Rotation・・・回転情報を固定します。x,y,zのチェックした値が固定されます。つまりチェックした項目が回転しなくなります。


Rigid bodyのスクリプトについての解説は↓の記事で行なっています。

<わからない事があったら>

このサイトの説明ではよくわからなかったとか、もっと知りたい事などがあれば、また別の勉強方法があるので違った切り口を使ってみるのもいいと思います。

<オススメの本>

本で詳しい解説がされているので書籍を買ってみるというのも手の一つです。最近はKindle版があるので届くまで待つ事もなく場所も取らないのでとても良いです。

<オンラインスクール>

オンラインスクールでは人に質問する事ができるので、行き詰まってしまった方にオススメです。 無料体験もあるので試しに見てみるのも手ですよ



タイトルとURLをコピーしました