概要
Unityは、3Dゲームだけでなく、2Dゲーム開発のための専用のツールと物理エンジン(Box2D)も搭載しています。3Dの物理演算がRigidbodyやBoxColliderなどで行われるのに対し、2Dの物理演算は、末尾に2Dと付いた専用のコンポーネント群、Rigidbody2D と Collider2D を使って行われます。
3Dと2Dの物理コンポーネントは互いに干渉せず、完全に独立して動作します。そのため、2Dゲームを開発する際は、必ず2D系のコンポーネントを使用する必要があります。間違えて3D用のコンポーネントを追加してしまうのは、初心者がよく陥る間違いの一つです。
この記事では、2D物理演算の心臓部であるRigidbody2Dと、衝突判定の形状を定義するCollider2Dの基本的な使い方について解説します。
Rigidbody2D: 2D物理演算の主役
Rigidbody2Dは、ゲームオブジェクトを2D物理エンジンの管理下に置くためのコンポーネントです。これを追加することで、オブジェクトは重力の影響を受けたり、力に応じて動いたり、他のオブジェクトと衝突したりするようになります。
Rigidbodyとの主な違い
- 2D専用: Z軸方向の移動や回転は行いません。すべての物理計算はXY平面上で完結します。
- 回転: 3Dでは回転が
Quaternion(四元数)で扱われるのに対し、2DではZ軸周りの回転のみなので、単純なfloat値(角度)で扱われます。
Body Type(ボディタイプ)
Rigidbody2Dには、オブジェクトの挙動を大きく変える3つのBody Typeがあります。
- Dynamic: デフォルトのタイプ。物理法則(力、重力、衝突)に完全に従って動きます。プレイヤーキャラクターや、投げられたボールなど、動的なオブジェクトに使用します。
- Kinematic: 物理的な力(重力や衝突による反発)の影響を受けませんが、スクリプトから
velocity(速度)やMovePosition()(位置)を設定することで動かすことができます。他のDynamicなオブジェクトを押したり、衝突イベントを発生させたりすることは可能です。動く床や、スクリプトで厳密に制御したい敵キャラクターなどに使用します。 - Static: 物理演算の影響を一切受けず、空間に完全に固定されます。
Kinematicと似ていますが、スクリプトから動かすことも想定されていません。地面や壁など、全く動かない静的なオブジェクトに使用します。パフォーマンス的には最も軽量です。
Collider2D: 衝突の形状を定義する
Collider2Dは、オブジェクトの物理的な形状を定義するためのコンポーネントです。物理エンジンは、このCollider2Dの形状を使って衝突判定を行います。目に見えるSpriteの形ではなく、Collider2Dの形が物理的な実体となります。
主なCollider2Dの種類
BoxCollider2D: 四角形の形状。最も一般的で、パフォーマンスも良いです。壁、床、キャラクターの基本的な当たり判定などに広く使われます。CircleCollider2D: 円形の形状。ボールや、角のないキャラクターなどに適しています。回転しても当たり判定の形が変わらないという利点があります。CapsuleCollider2D: カプセル(長円)形の形状。プレイヤーキャラクターの当たり判定として非常に人気があります。角がないため、坂道や小さな段差で引っかかりにくいというメリットがあります。PolygonCollider2D: Spriteの形状に合わせて、自動的に多角形の当たり判定を生成してくれます。複雑な地形や、精密な当たり判定が必要なオブジェクトに使用しますが、頂点数が多くなるとパフォーマンスに影響します。CompositeCollider2D: 複数のCollider2Dを一つに結合して、より複雑な形状を作成したり、パフォーマンスを最適化したりするために使用します。例えば、タイルマップで生成された多数のBoxCollider2Dを一つにまとめる、といった使い方をします。
Is Trigger(トリガー)
Collider2DのIs Triggerチェックボックスをオンにすると、そのコライダーは物理的な衝突(反発や押し出し)を起こさなくなります。代わりに、他のコライダーと重なったときにトリガーイベント(OnTriggerEnter2D, OnTriggerExit2D)を発生させるようになります。
これは、アイテムの取得エリアや、特定のゾーンに入ったことを検知するセンサーなど、物理的な反発は不要で、重なったという事実だけが欲しい場合に使用します。
衝突イベントの検知
Rigidbody2Dを持つオブジェクトがCollider2Dと衝突すると、スクリプトでそのイベントを受け取ることができます。
OnCollisionEnter2D(Collision2D collision): 物理的な衝突が始まった瞬間に呼ばれます。OnTriggerEnter2D(Collider2D other): トリガーに他のコライダーが侵入した瞬間に呼ばれます。
using UnityEngine;
public class PlayerController2D : MonoBehaviour
{
// 物理的な衝突を検知
private void OnCollisionEnter2D(Collision2D collision)
{
// 衝突した相手のタグが"Enemy"だったら
if (collision.gameObject.CompareTag("Enemy"))
{
Debug.Log("敵と衝突した!");
}
}
// トリガーイベントを検知
private void OnTriggerEnter2D(Collider2D other)
{
// 侵入してきた相手のタグが"Coin"だったら
if (other.CompareTag("Coin"))
{
Debug.Log("コインを取得!");
Destroy(other.gameObject); // コインを消す
}
}
}
まとめ
2D物理演算を正しく理解することは、面白い2Dゲームを作るための鍵です。
- 2Dゲームでは、必ず
Rigidbody2DとCollider2Dを使用する。 Rigidbody2DのBody Type(Dynamic, Kinematic, Static)をオブジェクトの役割に応じて正しく設定する。Collider2Dでオブジェクトの物理的な形状を定義する。シンプルな形状ほどパフォーマンスが良い。- 物理的な反発が不要な場合は
Is Triggerをオンにする。
これらのコンポーネントを組み合わせ、OnCollisionEnter2DやOnTriggerEnter2Dといったイベントをスクリプトで処理することで、キャラクターのジャンプ、アイテムの取得、敵との戦闘といった、ゲームの基本的なインタラクションを実装していくことができます。