2025年4月1日火曜日

【Unity 2D】Rigidbody2D の Body Type について

Rigidbody2D には 3 つの Body Type(物理特性)があり、それぞれ物理エンジンとの関わり方が異なります。

Dynamic

・デフォルトの設定
・物理計算の影響を受ける(通常の動くオブジェクト)
・重力・力・衝突の影響を受ける

Kinematic

・手動で動かせるが、物理計算の影響は受けない
・重力・力の影響なし、衝突判定のみ
・MovePosition() や MoveRotation() を使って動かす

Kinematicの使い所

・プレイヤーが操作するオブジェクト
・エスカレーターや動く足場

Static

・完全に固定されたオブジェクト
・動かない、衝突のみ処理される

Staticの使い所

・地面や壁
・ゴール地点などの判定エリア(トリガー)
・建物や障害物

【Unity 2D】Collider2D の使い方

Unityでオブジェクトの衝突判定処理や当たり判定処理を提供するクラス「Collider2D」の解説です。

1. 前提条件

衝突判定や当たり判定を行うには、以下の要件を満たす必要があります。

・Rigidbody2D: どちらかのオブジェクトに Rigidbody2D をアタッチ
・Collider2D: 両方のオブジェクトに Collider2D をアタッチ
・Layer Collision Matrix: 必要に応じてレイヤー間の衝突を設定

2. オブジェクトに衝突処理イベントを記述

衝突判定には以下の3つのイベントがあります。Collier2Dコンポーネントを追加したゲームオブジェクトのスクリプトに記述すると機能します。

引数のcollisionは衝突相手の情報を持ちます。collision.gameObjectで衝突相手のゲームオブジェクトを取得できます。

// Collier2Dコンポーネントを追加したゲームオブジェクトのスクリプトに記述

// ■ 他のオブジェクトと衝突したときに呼ばれる
private void OnCollisionEnter2D( Collision2D collision )
{
    Debug.Log( $"{collision.gameObject.name} と衝突しました" );
}

// ■ 他のオブジェクトと衝突している間、呼ばれ続ける
private void OnCollisionStay2D( Collision2D collision )
{
    Debug.Log( $"{collision.gameObject.name} と接触中..." );
}

// ■ 他のオブジェクトとの衝突が終わったときに呼ばれる
// 例: 床から離れたときを検知して処理したり
private void OnCollisionExit2D(Collision2D collision)
{
    Debug.Log( $"{collision.gameObject.name} から離れました" );
}

引数 Collision2D について

Collision2Dクラスから取得できる情報
・collision.gameObject → 衝突したオブジェクト
・collision.relativeVelocity → 衝突したときの相対速度
・collision.contacts → 衝突した位置 (ContactPoint2D[])
・collision.collider → 衝突したコライダー
・collision.rigidbody → 衝突したオブジェクトの Rigidbody2D

接触点を取得する(collision.contactsを利用)

void OnCollisionEnter2D(Collision2D collision)
{
    foreach (ContactPoint2D contact in collision.contacts)
    {
        Debug.Log($"衝突位置: {contact.point}, 法線: {contact.normal}");
    }
}

3. 当たり判定処理の場合、isTriggerプロパティをONにする

オブジェクト同士が当たったとき、衝突処理(跳ね返る処理)をさせずに単に当たったことだけを検知させたい場合、isTriggerプロパティをONにします。

その場合、当たり判定のイベントは以下の3つとなります。こちらもCollier2Dコンポーネントを追加したゲームオブジェクトのスクリプトに記述すると機能します。

引数のcolliderは衝突相手の情報を持ちます。collider.gameObjectで衝突相手のゲームオブジェクトを取得できます。

// Collier2Dコンポーネントを追加したゲームオブジェクトのスクリプトに記述

// ■ 他のオブジェクトと接触したときに呼ばれる
private void OnTriggerEnter2D( Collider2D collider )
{
    Debug.Log( $"{other.gameObject.name} がトリガーに入りました" );
}

// ■ 他のオブジェクトと接触している間、呼ばれ続ける
private void OnTriggerStay2D( Collider2D collider )
{
    Debug.Log( $"{other.gameObject.name} がトリガー内にいます" );
}

// ■ 他のオブジェクトとの接触が終わったときに呼ばれる
private void OnTriggerExit2D( Collider2D collider )
{
    Debug.Log( $"{other.gameObject.name} がトリガーから出ました" );
}

引数 Collider2D について

Collider2Dクラスから取得できる情報
・collider.gameObject → 衝突したオブジェクト
・collider.transform → 衝突したオブジェクトの Transform
・collider.bounds → コライダーのバウンディングボックス

取得できない情報
・衝突の力
・接触した位置や法線

4. 衝突相手を特定する

タグ (Tag) やレイヤー (Layer) を使って特定のオブジェクトとの衝突だけを処理できます。

// タグを使う

private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Enemy"))
    {
        Debug.Log("敵と衝突!");
    }
}
// レイヤーを使う

if (collision.gameObject.layer == LayerMask.NameToLayer("Enemy"))
{
    Debug.Log("敵のレイヤーと衝突!");
}

【注目記事】

ゲーム用ドット絵の配色は「LOSPEC」で解決!