親オブジェクトにRigidbody、子オブジェクトにColliderを持たせる設計に関する技術資料
1. 概要
本資料では、親にRigidbodyを付与し、子にColliderのみを設定する構成のメリットや実装方法について解説します。
この構成は、複数の当たり判定(Collider)を持つオブジェクトで、物理シミュレーションや衝突判定を効率的に管理するために用いられます。
2. 基本構造と考え方
[親オブジェクト]
- Rigidbodyを持つ(物理計算の基準)
- Transformを制御し、全体の動きを管理する
[子オブジェクト]
- Colliderのみを持つ
- 部位ごとの衝突判定を行う
- 親のRigidbodyの動きに従う
3. 利点
[物理演算の統一管理]
Rigidbody
が親オブジェクトにあることで、オブジェクト全体が一体となって動作するRigidbody
を持つオブジェクトごとに物理計算が行われるため、無駄な計算が発生しない
[部位ごとの衝突判定]
- 子オブジェクトごとに異なる
Collider
を設定することで、どの部分が衝突したかを判別可能 collision.contacts[].thisCollider.name
を用いることで、衝突箇所を特定できる
[管理の容易さ]
- 子オブジェクトに
Rigidbody
を付けないことで、物理計算の負荷を削減 - 一部の子オブジェクトのみ
Physics.IgnoreCollision()
を用いて衝突無視が可能
4. シーン構成例
Player (親オブジェクト) → Rigidbody [○]
├─ Head (子オブジェクト) → BoxCollider [□]
├─ Body (子オブジェクト) → CapsuleCollider [□]
- Player:
Rigidbody
を持ち、物理計算の基準となる - Head/Body: それぞれ
Collider
を持ち、個別の衝突判定を行う
5. コードサンプル
[1] 親オブジェクト(Player)にRigidbodyを設定
親オブジェクトで Rigidbody
を持ち、子オブジェクトの Collider
との衝突を管理するスクリプトを作成します。
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Rigidbody rb;
void Start()
{
// Rigidbodyの取得
rb = GetComponent<Rigidbody>();
rb.mass = 1.0f;
rb.drag = 0.5f;
rb.useGravity = true;
}
void OnCollisionEnter(Collision collision)
{
foreach (ContactPoint contact in collision.contacts)
{
Debug.Log("衝突した部位: " + contact.thisCollider.name);
}
}
void OnTriggerEnter(Collider other)
{
Debug.Log("トリガーに入った部位: " + other.name);
}
}
[ポイント]
OnCollisionEnter()
でどのCollider
が衝突したかを判別OnTriggerEnter()
でトリガー範囲内に入ったことを検出thisCollider.name
で衝突した子オブジェクトを特定
[2] 子オブジェクト(Colliderのみ)
子オブジェクトには Collider
のみを設定し、親の Rigidbody
に依存させます。
using UnityEngine;
public class BodyPartCollider : MonoBehaviour
{
void OnCollisionEnter(Collision collision)
{
Debug.Log(gameObject.name + " に衝突した: " + collision.gameObject.name);
}
void OnTriggerEnter(Collider other)
{
Debug.Log(gameObject.name + " にトリガー衝突: " + other.gameObject.name);
}
}
[ポイント]
gameObject.name
を使うことで、衝突した子オブジェクトの名前を特定できるOnCollisionEnter()
やOnTriggerEnter()
を使うことで、部位ごとの処理が可能
[3] Physics.IgnoreCollision()
を使って一部の当たり判定を無視
特定の Collider
同士の衝突を無視したい場合は、Physics.IgnoreCollision()
を使用できます。
void Start()
{
Collider headCollider = transform.Find("Head").GetComponent<Collider>();
Collider bodyCollider = transform.Find("Body").GetComponent<Collider>();
// 頭と体の内部的な衝突を無視する
Physics.IgnoreCollision(headCollider, bodyCollider, true);
}
[ポイント]
Physics.IgnoreCollision()
を使用すると、特定の部位間での衝突を無視できる
6. 注意事項
[子オブジェクトに Rigidbody
を追加しない]
Rigidbody
は親オブジェクトのみに設定するのが基本- 子に
Rigidbody
を設定すると、意図しない動きが発生する可能性がある - 例外として、「独立して動くパーツ(剣・落下アイテム)」などは子オブジェクトにも
Rigidbody
を追加
[衝突が2回検出される場合]
- 子オブジェクトの
Collider
にOnCollisionEnter()
を設定すると、親と子の両方で衝突が検出される場合がある collision.contacts[].thisCollider.name
を使って判別することで回避可能
7. まとめ
- 構成の基本:
- 親オブジェクトに
Rigidbody
を配置 - 子オブジェクトに
Collider
を配置 Rigidbody
が親にあることで、物理挙動は一体として管理される
- 親オブジェクトに
- 衝突判定の詳細:
collision.contacts[].thisCollider.name
を利用することで、どの部位が衝突したかの判別が可能となり、細かい処理や演出が実現できる。
この構成により、複数部位にわたる衝突判定を効率的に行い、かつ物理挙動の統一管理を実現することが可能 となります。
ディスカッション
コメント一覧
まだ、コメントがありません