Bard は楽して暮らしたい

ゲームを作って思うこと、ゲームを遊んで思うこと

Unity

【Unity】Rigidbody や Collider の設定により変化する、当たり判定の性質 後編

投稿日:2018年2月11日 更新日:

Unity の機能の中でも、基礎中の基礎とも言える Collision。

参考書の通りにやれば、物理演算に基づいたそれらしい挙動は作れるのですが、実際のところ『Rigidbody』や『Collider』の設定によって細かく挙動の種類分けがなされており、これらをいじっていると、オブジェクト同士が衝突したりしなかったりで苦戦することがあります。

今回は、これらの設定によって変化する『当たり判定の性質の種別』をまとめてみます。

試行環境:Unity 2017.2.1p2

前編』では、『Rigidbody』と『Collider』の紹介と、それぞれが持つ要素について取り扱いました。

【Unity】Rigidbody や Collider の設定により変化する、当たり判定の性質 前編

後編』となる本稿では各コンポーネントの設定による具体的な挙動の変化について見ていきます。

↓の公式ドキュメントの一部について解説したような内容になりますので、原文が気になる方はこちらへ。

https://docs.unity3d.com/ja/current/Manual/CollidersOverview.html

 

1. 3種類の設定

Unity によると、当たり判定の相互作用の種類は、以下の3つが存在します。

  • Dynamic Rigidbody Collider(公式の表記は『Rigidbody Collider』ですが、区別を明確にするため『Dynamic』を付けて表記します。)
  • Kinematic Rigidbody Collider
  • Static Collider

ざっくり言うと、上へ行くほど「動的で負荷が重い」、下へ行くほど「静的で負荷が軽い」という性質。

これらについて、以下で具体的に取り扱っていきます。

2. Dynamic Rigidbody Collider

  • Rigidbody』と『Collider』を共に持つ
  • Rigidbody』の『Is Kinematic』が OFF

GameObject に『Rigidbody』と『Collider』をひっつけて、何もいじっていない初期設定のままだと、この状態になります。

ちなみに 2D 用コンポーネントの場合は「『Is Kinematic』が OFF =『Body Type』が『Dynamic』」にあたるため、↓こんな感じ。

(本稿で『Dynamic Rigidbody Collider』と表記しているのは、この表示に基づいています)

この『Dynamic Rigidbody Collider』は、 いわゆる「物理演算に支配されたオブジェクト」になります。

つまり『Rigidbody』の『Use Gravity』にチェックが入っていれば、重力に従って Y軸 マイナス方向に加速し、左から他のオブジェクトがぶつかれば、右への力が加わって弾かれます。

2.1. 挙動の例

  • 上の Cube:Dynamic Rigidbody ColliderUse GravityONIs TriggerOFF
  • 下の Cube:Dynamic Rigidbody ColliderUse GravityOFFIs TriggerOFF

Dynamic Rigidbody Collider』同士の衝突例です。

上の Cube は重力に従って落下します。

下の Cube には重力は働きませんが、上の Cube に押される力によって、共に落下していきます。

  • 上の Cube:Dynamic Rigidbody ColliderUse GravityONIs TriggerOFF
  • 下の Cube:Dynamic Rigidbody ColliderUse GravityOFFIs TriggerON

前編』で取り上げた『Collider』の『Is Trigger』をいじったパターンです。

下の Cube が『Trigger』となったことで、衝突による物理的な力の働きは無くなりました。

ただし画面下部のログにも出力している通り、侵入判定を取ることは出来ています*1

また、以下は個人的な推測ですが…。

Dynamic Rigidbody Collider』は「物理演算による挙動」を前提としているため、おそらくスクリプト内で『transform.position』や『transform.localPosition』などを直接変更して座標を移動させる、という処理を推奨していないと思われます。

これらを動かす処理をスクリプト中に記述したい場合は、物理演算に基づいた処理である『Rigidbody.AddForce』などを使用すべき、と思われます。

Transform』をいじるタイプの座標移動処理は、下記『Kinematic Rigidbody Collider』に対して適用しましょう。

3. Kinematic Rigidbody Collider

  • Rigidbody』と『Collider』を共に持つ
  • Rigidbody』の『Is Kinematic』が ON

2D 版は「『Is Kinematic』が ON =『Body Type』が『Kinematic』」であるため、↓こんな感じ。

Kinematic Rigidbody Collider』は「物理演算の影響を受けず、スクリプトで物理挙動を制御するオブジェクト」になります。

ノーコードな開発ならともかく、プログラマが当たり判定を伴うゲームを制作する場合、多くはこれを選択することになると思います。

重力の影響も、他のオブジェクトが衝突した際の挙動も、そのままでは一切の処理が行われません。『前編』で紹介した『OnCollision ~』系の関数などの中に、処理を記述しましょう。

3.1. 挙動の例

  • 上の Cube:Dynamic Rigidbody ColliderUse GravityONIs TriggerOFF
  • 下の Cube:Kinematic Rigidbody ColliderIs TriggerOFF

下の Cube は衝突の影響を一切受けません。

対して上の Cube は、下の Cube への衝突を感知して、上へ乗る形で停止するようです。

  • 上の Cube:Dynamic Rigidbody ColliderUse GravityONIs TriggerOFF
  • 下の Cube:Kinematic Rigidbody ColliderIs TriggerON

下の Cube の『Is Trigger』を ON にしたパターン。

ログ出力の通り、衝突判定はしっかり検知されていますが、上の Cube の物理挙動には直接影響を与えていません。

  • 上の Cube:Kinematic Rigidbody ColliderIs TriggerOFF落下用スクリプト付き
  • 下の Cube:Kinematic Rigidbody ColliderIs TriggerOFF

上の Cube の自由落下処理をコードで記述した『Kinematic Rigidbody collider』同士の衝突。両者ともにトリガーではない状態。

ログ出力にも表示が無いため、衝突は一切検知されないようです。

ちなみにスクリプトは超シンプルに↓こんなので動かしています。


using UnityEngine;

public class FallDownTest : MonoBehaviour
{
    Transform mTransform;

    // Use this for initialization
    void Start()
    {
        mTransform = this.transform;
    }

    // Update is called once per frame
    void Update()
    {
        mTransform.localPosition = mTransform.localPosition + Vector3.down * 0.1f;
    }
}

 

  • 上の Cube:Kinematic Rigidbody ColliderIs TriggerOFF落下用スクリプト付き
  • 下の Cube:Kinematic Rigidbody ColliderIs TriggerON

片方をトリガー化したパターン。

こちらの場合は衝突が検知され、コールバック関数が呼ばれるようです。ちょっと不思議ですね。

だんだんと組み合わせがややこしくなって来ましたが、先にリンクを紹介した公式ドキュメント

https://docs.unity3d.com/ja/current/Manual/CollidersOverview.html

の一番下に、コールバック関数が呼ばれるかどうかが、表になってまとまっています。

3.2. 2D コンポーネントの場合…

Rigidbody 2D』の場合のみ、さらにもう1つ『Use Full Kinematic Contacts』という要素が追加されています。

これを ON にすると『Kinematic Regidbody Collider』同士の衝突を検知できるようになります(上の『挙動の例』3つ目で、検知できていなかったケース)。

  • 上の Sprite:Kinematic Rigidbody ColliderIs TriggerOFFUse Full Kinematic ContactsON落下用スクリプト付き
  • 下の Cube:Kinematic Rigidbody ColliderIs TriggerOFFUse Full Kinematic ContactsOFF

トリガー化されていないオブジェクト同士でも、衝突を検知することが可能になっています。

衝突を見る対象が増えるため、おそらく処理についても、一段階重いものになっていると思われます。この辺りいつか検証してみたい。

Rigidbody 2D』の詳しい特徴については↓こちら

https://docs.unity3d.com/ja/current/Manual/class-Rigidbody2D.html

4. Static Collider

  • Collider』のみを持ち『Rigidbody』を持たない

最も静的なケースで、つまるところ「当たり判定は持つけれど、動かないオブジェクト」を前提としています。多くの場合、マップ地形などがこれにあたると思われます。

↓ 2D コンポーネントでは「『Body Type』が『Static』」のケースがこれにあたります。2D の場合は『Rigidbody 2D』を持たせておくことが許容されるのですね。

おそらく、動かさない限りは最も処理負荷が少ないケースです。ただし公式ドキュメントによると「これを勝手に動かす(含スケーリング)と、物理演算処理のパフォーマンスが著しく低下する」ようです。

おそらく物理演算において、衝突を検知する対象の中で動くオブジェクトは『Dynamic ~』と『Kinematic ~』に限られ、『Static Rigidbody Collider』は動かない、という前提で処理を行っているものだ、と推測されます。

5. おわりに

当たり判定をエンジンで持たせると、いろいろと処理が重くなるんじゃないかと思いますが、そこでなるべく軽量化するように Unity の機能を使って小手先の調整を行う際に、注意しておきたい情報をまとめてみました。

だいたいは例の公式ドキュメントの表を、実験したという感じです。また必要に応じて追記などできればと思います。

*1:本稿の動画において、ログ出力のスクリプトはすべて『上の Cube 側』に貼り付けています。

-Unity

執筆者:


  1. no name より:

    共同の図解についてですが、上下の箱が同色なのでぱっと見で分かりづらいと思うので、色を変えてみるといいのでは?と思いました。

comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

関連記事

BitSummit Vol.6

【ゲーム雑記】BitSummit Vol.6 を経て、期待のインディーゲーム一覧 後編

少し間が空いてしまいましたが、先月、京都で開催された BitSummit Vol.6 へ行ってきました。 その中で、プレイしたタイトルの感想や、未プレイながら目を引いたタイトルの紹介をしていきたいと思 …

UnityChanLicenseLogo

【Unity】Timeline 機能 Playable Track 用のスクリプトを書く際の基礎

最近 Unity の Timeline 機能について触れる機会が多く、基礎的な部分について社内 Wiki に情報を書いたりしていたので、コピペ的に再利用してまとめておきます。   試行環境: …

VoiSingRoid

【VOICEROID】歌う VOICEROID リズムゲーム『VoiSingRoid Ver.3.0.0』リリースしました

2019/10/14 追記Ver.3.0.0 へアップデートし、その内容を追記しました。 2019/07/23 追記Ver 2.0.0 へアップデートし、その内容を追記しました。 裏でコツコツと開発を …

BitSummit Vol.6

【ゲーム雑記】BitSummit Vol.6 を経て、期待のインディーゲーム一覧 前編

少し間が空いてしまいましたが、先月、京都で開催された BitSummit Vol.6 へ行ってきました。 その中で、プレイしたタイトルの感想や、未プレイながら目を引いたタイトルの紹介をしていきたいと思 …

【Unity】Unity 2017 で TextMesh Pro を使って作成したプロジェクトを Unity 2018 へ移行する際のエラー対策リンクまとめ

Unity 2017 で作成したプロジェクトを Unity 2018 へ移行すると、TextMesh Pro まわりでいろいろとエラーが出たので、そのときに参考にさせていただいた記事のリンク集です。 …