🎉

Unityの物理エンジン(Rigidbody)

2024/05/08に公開

GameObjectに物理挙動(物理アニメーション)を加える

Unityの「Rigidbody」は、Unity Technologiesが提供するUnityエンジンの一部です。
Unity Technologiesは、Unityゲームエンジンを開発している企業で、ゲーム開発だけでなく、映画産業、建築ビジュアライゼーション、自動車産業など、多様な分野でその技術が使用されています。

Unityエンジン自体が多くのデベロッパーにとってアクセスしやすいプラットフォームとなっており、その中のRigidbodyコンポーネントは物理演算を扱うための基本的なツールの一つです。このコンポーネントを使うことで、初心者でも比較的簡単に物理的な挙動をオブジェクトに追加することができます。

機能

この「Rigidbody」とは、オブジェクトに物理的な挙動を付与するためのコンポーネントです。
このコンポーネントをオブジェクトに追加することによって、Unityの物理エンジンにそのオブジェクトを組み込み、重力の影響を受けたり、他のオブジェクトとの衝突や摩擦などの物理的な相互作用を行うことができるようになります。

Rigidbodyには以下のような主要な機能があります:

  1. 重力の影響: Rigidbodyが付与されたオブジェクトは、重力の影響を受けて落下します。
  2. 力とトルクの適用: オブジェクトに対して力(pushやpull)やトルク(回転力)をプログラム的に適用することが可能です。
  3. 衝突検知: 他のオブジェクトとの衝突を検知し、その反応を制御することができます。
  4. 質量と抵抗の設定: オブジェクトの質量や空気抵抗、摩擦などの物理的特性を設定することができます。

これにより、ゲーム内でリアルな物理現象を再現することが可能になります。例えば、ボールが坂道を転がる、風によって物体が飛ばされる、オブジェクトが衝突して跳ね返るなど、多岐にわたる現象をシミュレートできます。

Unityで使える物理エンジン

Unityで使用できる主要な物理エンジンは主に2つあります。それぞれに特徴があり、用途に応じて選ぶことができます。

  1. PhysX: Unityのデフォルトの物理エンジンであり、NVIDIAによって開発されました。このエンジンは、リアルタイムの3D物理シミュレーションに最適化されており、衝突検出、剛体動力学、布のシミュレーションなど、多くの物理演算をサポートしています。RigidbodyコンポーネントもこのPhysXを基に動作しています。

  2. Havok Physics: UnityではオプションとしてHavok Physicsも利用できます。Havokは、より複雑な物理演算や大規模な環境での精密なシミュレーションが求められる場合に適しています。特に大量のオブジェクトが関与するシーンでのパフォーマンスが優れているとされています。

これらの物理エンジンは、それぞれ異なる特徴を持っており、プロジェクトのニーズに合わせて選択することが重要です。例えば、より高度な物理演算が必要な場合はHavokを検討することがありますが、一般的な用途ではデフォルトのPhysXで十分なことが多いです。

PhysXとHavokは両方とも高度な物理演算を提供するエンジンですが、それぞれに特徴があります。
以下に、それぞれのメリットとデメリットを説明します。

PhysX

メリット:

  1. 統合性: Unityにデフォルトで組み込まれており、多くのUnity開発者にとってアクセスしやすい。
  2. リアルタイムシミュレーション: 物理演算がリアルタイムで行われ、ゲーム内で自然な動きを再現する。
  3. 多機能性: 剛体、柔軟体、キャラクター制御など、広範な物理演算が可能。

デメリット:

  1. パフォーマンス: 大規模なシナリオや非常に多数のオブジェクトが絡む場面では、パフォーマンスが落ちる可能性がある。
  2. カスタマイズ性の限界: 複雑なカスタマイズや特定の物理挙動を再現する際に、限界がある場合がある。

Havok

メリット:

  1. スケーラビリティ: 大規模な物理演算に優れており、多数のオブジェクト間での複雑な相互作用を効率的に処理できる。
  2. 高度な物理特性: より詳細な衝突検出や破壊モデリングなど、高度な物理演算が可能。
  3. 最適化されたパフォーマンス: 大量のデータ処理も高速に行えるため、大規模なゲームに適している。

デメリット:

  1. 導入の複雑さ: Unityでの標準統合がないため、導入がPhysXに比べて複雑になる可能性がある。
  2. ライセンスコスト: Unity ProやEnterpriseが必要であり、追加コストが発生する可能性がある。

それぞれの使用感

PhysXとHavokは、Unity内で利用できる二つの主要な物理エンジンで、それぞれ異なる用途とメリットがあります。PhysXはUnityにデフォルトで組み込まれており、多くの開発者にとってアクセスしやすいオプションです。
基本的な物理演算、如何なるリアルタイムの反応と幅広い物理現象のシミュレーションが可能ですが、非常に複雑なシナリオや大規模なシミュレーションでのパフォーマンスは限界があります。

一方、Havok Physicsはより高度な物理シミュレーションを求める大規模なプロジェクト向けに設計されており、特に多数のオブジェクトが関与する環境での効率的な処理能力を持っています。Havokは高度な破壊モデリングや精密な衝突検出などを特徴としていますが、Unity ProやEnterpriseライセンスが必要であり、導入のハードルが高いことがデメリットとされています。

どちらのエンジンもその特性に応じて、開発者がプロジェクトの要求に基づいて選択することができます。
PhysXは手軽に始められる一方で、Havokはより専門的なニーズに対応する能力を持っています。

Colliderについて

Colliderは物理エンジンそのものではなく、Unityにおいてオブジェクトがどのように衝突を検出するかを定義するコンポーネントです。今回Rigidbodyを使うにあたり、簡単に理解をしていきます。

Colliderはゲーム内のオブジェクトに「形」を与え、他のオブジェクトや環境との物理的なインタラクション(接触や衝突)を可能にします。
Unityでは、物理エンジン(例えばPhysX)がこれらのColliderを使用して、オブジェクト間の衝突を計算し、適切な物理的反応をシミュレートします。

Unityで一般的に使用されるColliderには以下のような種類があります:

  • Box Collider: 四角い箱の形をしたColliderで、主に直方体のオブジェクトに使用されます。
  • Sphere Collider: 球形のColliderで、球や円形のオブジェクトに適しています。
  • Capsule Collider: カプセル形状(長円形)のColliderで、人間のキャラクターなどによく使用されます。
  • Mesh Collider: オブジェクトのメッシュを直接使用して、より複雑な形状のColliderを作成します。Probuilderに使われるColiderです。

Colliderは直接的な力学計算を行わないため、物理エンジンではないですが、物理エンジンがどのようにオブジェクト間の相互作用を扱うかを決定するために不可欠です。Colliderがなければ、オブジェクトは互いに「通り抜け」てしまい、リアルな物理反応は実現しません。

Rigidbody(PhysX)を使う

Unityで標準のPhysX物理エンジンを使う基本的な方法を説明します。
これを使うと、GameObjectにリアルな物理挙動を追加できます。

1. Rigidbodyコンポーネントの追加

物理演算を行いたいオブジェクトには、まずRigidbodyコンポーネントを追加する必要があります。これにより、オブジェクトが重力の影響を受けたり、力を受けて動くようになります。

  • Unityエディタでオブジェクトを選択します。
  • Inspectorウィンドウで「Add Component」ボタンをクリックし、「Physics」カテゴリから「Rigidbody」を選択して追加します。

2. Colliderの設定

物理演算を利用するには、オブジェクトにCollider(衝突器)が必要です。これがないと、オブジェクトは他のオブジェクトとの物理的な衝突を検出できません。

  • 同じくオブジェクトを選択し、「Add Component」から「Collider」を選択します。例えば、「Box Collider」、「Sphere Collider」、「Capsule Collider」などがあります。
  • Colliderの形状とサイズをオブジェクトに合わせて調整します。

3. 物理演算のカスタマイズ

Rigidbodyのプロパティを調整して、オブジェクトの物理挙動をカスタマイズできます。重要なプロパティには以下のようなものがあります。

  • Mass(質量): オブジェクトの重さ。
  • Drag(抗力)とAngular Drag(回転抗力): オブジェクトが移動や回転する際の空気抵抗のようなもの。
  • Use Gravity(重力を使用): オブジェクトが重力の影響を受けるかどうか。
  • Is Kinematic(キネマティックを使用): このオプションを有効にすると、物理エンジンがオブジェクトの運動を制御しなくなり、アニメーションやスクリプトで完全に制御されるようになります。

4. スクリプトを使用した制御

Unityのスクリプト(C#)を使って、物理演算の動作をプログラム的に制御することもできます。
例えば、特定のイベントが発生したときにオブジェクトに力を加えるなどが可能です。

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    void Start()
    {
        Rigidbody rb = GetComponent<Rigidbody>();
        if (rb != null)
        {
            rb.AddForce(new Vector3(0, 10, 0), ForceMode.Impulse);
        }
    }
}

このスクリプトはオブジェクトに瞬間的な力(上向き)を加える例です。
ForceMode.Impulseはその瞬間に力を加えるモードを指定しています。
このスクリプトは、ゲームを再生するとY軸方向に力が働きます。

動作確認

それでは、Unityで物理演算をカスタマイズしてテストする方法について手順を説明していきます。
これは、特定の物理設定を試すことで、ゲームの挙動を理解しやすくするための基本的なアプローチです。

ステップ 1: 基本的なセットアップ

  1. 新しいUnityプロジェクトを作成します。
  2. シーンに平面(Plane)オブジェクトを追加し、これを地面とします。
  3. 新しい球体(Sphere)オブジェクトを作成し、地面の上に配置します。これが物理演算のテスト対象になります。

ステップ 2: RigidbodyとColliderの追加

  1. 球体にRigidbodyコンポーネントを追加します。これにより、重力や他の力が球体に影響を与えるようになります。
  2. 球体には既にSphere Colliderが付いていることを確認します。これがないと、球体は地面を通り抜けてしまいます。

ステップ 3: 物理パラメータのカスタマイズ

  1. Rigidbodyのパラメータを調整します。Inspectorウィンドウで以下のように設定できます:
    • Mass(質量): オブジェクトの重さを増やしてみて、落下速度や衝撃の違いを観察します。
    • Drag(抗力)とAngular Drag(回転抗力): これらを調整して、空気抵抗がオブジェクトの動きにどう影響するかを見ます。
    • Use Gravity: このオプションをオフにして重力の影響を無視する場合の動きをテストします。

ステップ 4: 力とトルクの適用

  1. 新しいスクリプトを作成し、球体にアタッチします。
  2. スクリプトに以下のようなコードを書き込んで、起動時に力を加えてみます。
    using UnityEngine;
    
    public class ForceApplier : MonoBehaviour
    {
        void Start()
        {
            Rigidbody rb = GetComponent<Rigidbody>();
            if (rb != null)
            {
                // 力を加える
                rb.AddForce(new Vector3(0, 0, 500));  // 前方に力を加える
            }
        }
    }
    
    このスクリプトは、球体が前方に力を受けて動き出すようにします。

ステップ 5: シミュレーションの実行と観察

  1. UnityエディタのPlayボタンを押してシミュレーションを実行します。
  2. 球体がどのように動くか観察し、パラメータの違いがどのように挙動に影響するかをノートしてみましょう。

ステップ 6: 結果の評価

  • シミュレーションを何度か繰り返し、異なる設定でテストして、物理演算の理解を深めます。

このプロセスを通じて、Unityの物理システムの基本を理解し、さまざまな物理パラメータがゲームオブジェクトの挙動にどのように影響するかを体験できます。実際のゲーム開発においても、このようなテストを繰り返

ことが可能になります。これにより、デベロッパーはプロジェクトに最適な物理設定を見つけるための理解を深めることができます。

スクリプトからコントロールする

Unityスクリプトを使ってオブジェクトをコントロールするケースは多岐にわたります。
主に次のようなシチュエーションでスクリプトを利用します:

  1. ユーザー入力に反応する:プレイヤーのキーボード入力やマウス操作に応じてオブジェクトを動かす場合、スクリプトを使用してリアルタイムで反応させることができます。
  2. 自動化された動き:オブジェクトに一定のパターンやルールに基づく動き(例えば、パトロールする敵キャラクター)を与える場合にもスクリプトが使用されます。
  3. ゲームの物理的反応をカスタマイズする:特定のイベントが発生したときにオブジェクトに力を加えたり、特定の方向に動かしたりするためにスクリプトを利用します。

ForceModeについて

Rigidbody.AddForce() メソッドは、オブジェクトに力を加える際に使用します。このメソッドは ForceMode パラメータを利用して、力の加え方を指定できます。ForceMode には以下の4つのオプションがあります:

  • Force:連続的な力を加え、質量に基づいて加速します(デフォルト)。
  • Acceleration:質量を無視して連続的な加速を与えます。
  • Impulse:瞬間的な力(インパルス)を加え、質量に基づいて加速します。
  • VelocityChange:質量に関係なく、瞬間的に速度を変更します。

サンプルスクリプト

以下のスクリプトは、プレイヤーがスペースバーを押した時にオブジェクトに上向きのインパルスを加える例です:

using UnityEngine;

public class JumpScript : MonoBehaviour
{
    Rigidbody rb;

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

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // スペースバーを押すと上向きのインパルスを加える
            rb.AddForce(Vector3.up * 5, ForceMode.Impulse);
        }
    }
}

このスクリプトは、Rigidbody コンポーネントがアタッチされたオブジェクトに対して、スペースバーが押されたときに上向きの力(インパルス)を加え、オブジェクトが跳ねるようにします。
ForceMode.Impulse は、力を瞬間的に加えるために使用され、特にジャンプのような動きに適しています。

Discussion