1つのGameObjectに2つのColliderをアタッチする設計に関する技術資料
目次
1. 概要
本資料では、1つのGameObjectに複数のColliderをアタッチする構成 のメリット、実装方法、考慮点について解説します。
この構成は、異なる形状や当たり判定を1つのオブジェクトに持たせる必要がある場合に有効 です。
2. 基本構造と考え方
(1) なぜ1つのGameObjectに複数のColliderを持たせるのか?
- 複雑な当たり判定を作成できる
- 異なる形状(BoxCollider + SphereCollider など)を組み合わせることで、複雑なオブジェクト形状に対応
- 例: キャラクターの体にCapsuleCollider、手にSphereCollider
- 部分ごとの衝突処理を区別できる
- 1つの
Rigidbody
に対して、どのColliderが衝突したかを判別可能 collision.contacts[].thisCollider.name
を使用して判別
- 1つの
- トリガーエリアと通常の衝突判定を同時に実装できる
- 例: 通常のBoxCollider(
isTrigger=false
)に加え、検出用のSphereCollider(isTrigger=true
)を持たせる
- 例: 通常のBoxCollider(
3. 利点
(1) 物理計算を統一できる
- 1つの
Rigidbody
でオブジェクトの物理挙動を管理できる - 各Colliderが個別にRigidbodyを持つと、不安定な物理挙動が発生する可能性がある
(2) 部位ごとの衝突判定が可能
collision.contacts[].thisCollider.name
を利用して、どのColliderが衝突したか判別できる
(3) トリガーと通常の衝突を分離
- トリガー(
isTrigger=true
) を活用し、範囲検出と通常の衝突を分けて管理 できる
4. シーン構成例
Robot (GameObject) → Rigidbody
├─ BoxCollider (体) → `isTrigger = false`
├─ SphereCollider (センサー) → `isTrigger = true`
- BoxCollider → 物理衝突のため(壁や敵との衝突を検知)
- SphereCollider → トリガーエリア(プレイヤーが近づいたことを検知)
5. コードサンプル
(1) 1つのオブジェクトに複数のColliderを設定
以下のスクリプトを Robot
にアタッチし、2つのColliderの衝突を個別に検出します。
using UnityEngine;
public class MultiColliderObject : MonoBehaviour
{
private Rigidbody rb;
private Collider[] colliders;
void Start()
{
// Rigidbodyの取得
rb = GetComponent<Rigidbody>();
// すべてのColliderを取得
colliders = GetComponents<Collider>();
// 各Colliderの名前をログに表示(デバッグ用)
foreach (Collider col in colliders)
{
Debug.Log("登録されたCollider: " + col.name);
}
}
void OnCollisionEnter(Collision collision)
{
foreach (ContactPoint contact in collision.contacts)
{
Debug.Log("衝突したCollider: " + contact.thisCollider.name);
}
}
void OnTriggerEnter(Collider other)
{
Debug.Log("トリガーに入ったCollider: " + other.name);
}
}
ポイント
GetComponents<Collider>()
を使用して、すべてのColliderを取得collision.contacts[].thisCollider.name
を使用して、衝突したColliderを特定OnTriggerEnter()
を使用して、トリガーエリアへの進入を検出
(2) 物理衝突とトリガーを分ける
通常の Collider
(物理衝突用)と Trigger Collider
(範囲検出用)を区別して処理を分ける例です。
void OnCollisionEnter(Collision collision)
{
foreach (ContactPoint contact in collision.contacts)
{
if (contact.thisCollider.name == "BoxCollider")
{
Debug.Log("物理衝突: 体に当たった!");
}
}
}
void OnTriggerEnter(Collider other)
{
if (other.name == "SphereCollider")
{
Debug.Log("プレイヤーがセンサー範囲に入った!");
}
}
ポイント
contact.thisCollider.name == "BoxCollider"
で物理衝突を検出other.name == "SphereCollider"
でトリガー範囲への進入を検出
6. Physics.IgnoreCollision()
を使用して特定のColliderを無視
特定の Collider
同士の衝突を無視したい場合は、Physics.IgnoreCollision()
を使用できます。
void Start()
{
Collider boxCollider = GetComponent<BoxCollider>();
Collider sphereCollider = GetComponent<SphereCollider>();
// 物理衝突を無視(ただしトリガーイベントは発生する)
Physics.IgnoreCollision(boxCollider, sphereCollider, true);
}
ポイント
Physics.IgnoreCollision()
を使うと、特定のCollider間の物理衝突を無効化isTrigger = true
なら、トリガーイベントは発生する
7. 注意事項
(1) 同じオブジェクト内のCollider同士が意図せず衝突する場合
- Unityは同じ
GameObject
内のCollider
同士は基本的に衝突しない - しかし、親子関係の
Collider
やスクリプトによる動的変更で衝突することがある Physics.IgnoreCollision()
を適切に使用することで回避可能
(2) Rigidbody
は1つにする
- 1つの
GameObject
に 複数のRigidbody
を持たせると、物理挙動が不安定になる Rigidbody
は親オブジェクトに1つだけ設定 する
8. まとめ
項目 | 内容 |
---|---|
1つのGameObjectに複数のColliderを持たせる理由 | 異なる形状の当たり判定を1つのオブジェクトに持たせるため |
物理計算の管理 | Rigidbodyは1つだけ持たせ、Colliderごとに異なる処理を行う |
衝突の判別方法 | collision.contacts[].thisCollider.name を使い、どのColliderが衝突したかを取得 |
トリガーと物理衝突を分離 | OnTriggerEnter() と OnCollisionEnter() を分けて処理 |
特定のCollider間の衝突を無視 | Physics.IgnoreCollision() を使用 |
9. 結論
- 1つの
GameObject
に複数のCollider
を持たせることで、より詳細な衝突判定が可能 - トリガーと物理衝突を分けて管理することで、ゲームロジックを整理しやすい
- 適切なスクリプトを活用することで、安定した物理挙動を実現できる
ディスカッション
コメント一覧
まだ、コメントがありません