Unity初心者向け:Rigidbodyで学ぶ物理演算と衝突判定の基本

Unityは、ゲーム開発において非常に強力なツールです。中でも物理演算と衝突判定は、リアルな動きや挙動を表現するために欠かせない機能です。

この記事では、Unity初心者向けにRigidbodyの役割と主要なプロパティであるMass(質量)、Drag(空気抵抗)、Gravity(重力)の使い方について、具体例を交えながら分かりやすく解説します。

Rigidbodyとは?

Rigidbodyは、Unityの物理シミュレーションを有効にするコンポーネントです。これをオブジェクトに追加することで、重力の影響や衝突時の物理的な反応を自動的に計算してくれます。Rigidbodyを利用することで、キャラクターやオブジェクトにリアルな動きを付加することができます。

  • 物理演算の有効化
    Rigidbodyを追加することで、オブジェクトが物理法則に従って動くようになります。例えば、重力に引かれて落下する、他のオブジェクトと衝突すると反応するなどの動作が自動的に計算されます。
  • 衝突判定との連携
    Rigidbodyを持つオブジェクトは、Colliderコンポーネントと組み合わせることで、他のオブジェクトとの衝突を検知できます。これにより、ゲーム内での接触判定や跳ね返りなどが実現されます。

Rigidbodyの主要プロパティ

Rigidbodyには多くのプロパティがありますが、ここでは特に重要な3つについて説明します。

Mass(質量)

概要

Massはオブジェクトの質量を表す値で、物理演算時に衝突の反応や運動量の計算に影響します。質量が大きいほど、力を加えても動きにくく、また衝突時の反発力が変わってきます。

利用例
  • 軽いオブジェクト:Massの値を小さく設定(例:0.5〜1)
  • 重いオブジェクト:Massの値を大きく設定(例:10以上)
注意点

実際のシーン内で複数のオブジェクトが衝突する場合、質量のバランスを考えることで、より現実的な動きを表現することができます。

Drag(空気抵抗)

概要

Dragはオブジェクトが移動する際の抵抗力(減速)を示します。Dragの値が高いと、オブジェクトは移動中に徐々にスピードが落ちやすくなります。これにより、急激な動きを抑え、より自然な減速を実現できます。

利用例
  • 風の影響を受けやすいオブジェクト:Dragの値をやや高めに設定
  • 滑らかに動く物体:Dragの値を低めに設定
注意点

ドラッグが大きすぎると、オブジェクトの動きが過度に鈍くなり、ゲームプレイに影響を与える可能性があるため、適切な値を見極めることが大切です。

Gravity(重力)

概要

Gravityは、オブジェクトに重力の影響を受けるかどうかを指定するプロパティです。通常、Rigidbodyを持つオブジェクトは重力が自動的に働き、自然落下します。Gravityのチェックを外すと、重力の影響を受けずに任意の動きを制御することができます。

利用例
  • 自然な落下:Gravityのチェックをオン
  • 空中に固定したい場合やカスタムな動き:Gravityのチェックをオフにしてスクリプトで制御
注意点

重力の影響を除外する場合、他の力(例えば、移動スクリプトなど)で動きを調整する必要があります。

Rigidbodyの設定方法と基本スクリプト

Unityエディター上でRigidbodyをオブジェクトに追加する方法は非常に簡単です。オブジェクトを選択し、インスペクターウィンドウで「Add Component」ボタンをクリックして「Rigidbody」を追加します。ここで、Mass、Drag、Gravityの各プロパティを調整できます。

また、C#スクリプトからもこれらのプロパティを設定・変更することが可能です。以下は簡単な例です。

using UnityEngine;

public class RigidbodyController : MonoBehaviour
{
    // Rigidbodyコンポーネントへの参照
    private Rigidbody rb;

    // 初期設定
    void Start()
    {
        // Rigidbodyコンポーネントを取得
        rb = GetComponent<Rigidbody>();

        // 質量の設定(例:5)
        rb.mass = 5f;

        // 空気抵抗の設定(例:0.5)
        rb.drag = 0.5f;

        // 重力の影響を有効にする
        rb.useGravity = true;
    }

    // 更新処理
    void Update()
    {
        // 簡単な移動操作の例(矢印キーによる移動)
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        rb.AddForce(movement * 10f);
    }
}

このスクリプトは、Rigidbodyを利用してオブジェクトに力を加え、ユーザーの入力に応じてオブジェクトを移動させる例です。

MassやDragの設定は、オブジェクトの動作に大きな影響を与えるため、シーンの意図に合わせて調整してください。

衝突判定とトリガーの利用

Unityでは、RigidbodyとColliderコンポーネントを組み合わせることで、衝突判定が行えます。Colliderはオブジェクトの形状に合わせた「当たり判定領域」を提供し、他のColliderとの接触を検出します。

  • 通常の衝突判定
    Rigidbodyが付与されたオブジェクト同士が衝突すると、物理演算に基づいて反発や衝突後の動きが計算されます。
  • トリガー
    Colliderの「Is Trigger」プロパティを有効にすると、衝突しても物理反応は起こらず、オブジェクトが領域内に入ったことを検知するためのイベント(OnTriggerEnterなど)が発生します。これにより、ドアの開閉やポイント取得などの処理が可能になります。

以下は、OnTriggerEnterを使った簡単な例です。

using UnityEngine;

public class TriggerExample : MonoBehaviour
{
    // 他のオブジェクトがトリガー領域に入ったときに呼ばれる
    void OnTriggerEnter(Collider other)
    {
        Debug.Log(other.name + "がトリガーに入った");
    }
}

Rigidbodyを使った基本シーンの作成例

ここでは、Rigidbodyを活用した基本シーンの例を紹介します。シーンには床、動くオブジェクト、そして障害物が配置されます。

  1. 床の作成
    平面(Plane)オブジェクトを作成し、Colliderは自動的に追加されます。床はRigidbodyは不要です。
  2. 動くオブジェクト
    Cubeオブジェクトを作成し、Rigidbodyコンポーネントを追加します。Mass、Drag、Gravityの値を適宜調整します。
    • Massを中程度に設定(例:2〜5)
    • Dragは低めに設定し、スムーズな移動を実現
    • Gravityはオンにして、自然な落下を再現
  3. 障害物
    他のCubeやSphereオブジェクトを配置し、Colliderを設定します。動くオブジェクトが障害物に衝突することで、反発や停止が発生します。

実践的な注意点

  • パフォーマンスの最適化
    多くのRigidbodyやColliderを使用すると、物理演算の計算負荷が増大するため、不要なオブジェクトにはRigidbodyを追加しないようにしましょう。
  • 正しいプロパティの設定
    ゲームの挙動に合わせてMassやDragの値を調整することが重要です。シーン内の各オブジェクトの役割に応じた値を設定し、現実的な物理挙動を実現してください。
  • デバッグとテスト
    物理演算は、実際にプレイしてみることで微調整が必要な場合があります。Unityの「Sceneビュー」や「Gameビュー」で実行結果を確認し、問題があれば設定を変更しましょう。

演習問題とその解答例

ここまでの内容を確認するために、以下の演習問題にチャレンジしてみましょう。

演習問題

  1. Rigidbodyの追加と設定
    次のシナリオを実装してください。
    • 新しいCubeオブジェクトを作成し、Rigidbodyを追加する。
    • RigidbodyのMassを3、Dragを0.3に設定する。
    • Gravityは有効にする。
  2. ユーザー入力によるオブジェクト移動
    Cubeオブジェクトが矢印キーの入力に応じて移動するスクリプトを作成しなさい。
    • 移動に加える力の大きさは、ユーザー入力に合わせて調整する。
  3. 衝突判定の実装
    Cubeオブジェクトが他のオブジェクトに衝突した際に、デバッグログで「衝突しました!」と表示されるようにする。Colliderがトリガー設定になっている場合と通常の衝突の場合で、どのイベント関数を使用するか答えなさい。

解答例

Rigidbodyの追加と設定

以下のスクリプト例は、Cubeオブジェクトに対してRigidbodyコンポーネントを取得し、指定のプロパティを設定するものです。

using UnityEngine;

public class CubeSetup : MonoBehaviour
{
    void Start()
    {
        Rigidbody rb = gameObject.AddComponent<Rigidbody>();
        rb.mass = 3f;       // 質量を3に設定
        rb.drag = 0.3f;     // Dragを0.3に設定
        rb.useGravity = true;  // Gravityを有効にする
    }
}
ユーザー入力によるオブジェクト移動

ユーザーの矢印キー入力に応じてCubeが動くスクリプトの例は以下の通りです。

using UnityEngine;

public class CubeMovement : MonoBehaviour
{
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        float moveX = Input.GetAxis("Horizontal");
        float moveZ = Input.GetAxis("Vertical");

        Vector3 force = new Vector3(moveX, 0, moveZ) * 10f;
        rb.AddForce(force);
    }
}
衝突判定の実装

通常の衝突の場合はOnCollisionEnter、トリガーの場合はOnTriggerEnterを使用します。
ここでは通常の衝突の例を示します。

using UnityEngine;

public class CollisionDetection : MonoBehaviour
{
    void OnCollisionEnter(Collision collision)
    {
        Debug.Log("衝突しました!");
    }
}

※ トリガー設定のColliderを使用している場合は、OnTriggerEnter(Collider other)を使用してください。

まとめ

この記事では、Unityにおける物理演算と衝突判定の基本概念として、Rigidbodyとその主要プロパティ(Mass, Drag, Gravity)について解説しました。

基本的な設定方法や簡単なスクリプト例、そして実践的な注意点を学ぶことで、初心者でも実際のシーンで応用できる知識を身につけることができます。また、演習問題を通じて実際に手を動かしながら理解を深めることができるため、ぜひ挑戦してみてください。

以上の内容を参考に、Unityの物理演算機能を使いこなし、よりリアルなゲーム世界の実現に役立ててください。