リンドくん先生、Unityでゲームを作ってるんですけど、オブジェクトを落としたり、ぶつけたりする方法がわからなくて...
たなべなるほど、それは物理シミュレーションの出番だね!
Unityには「Rigidbody」という便利なコンポーネントがあって、これを使うと重力や衝突をリアルに再現できるんだよ。
リンドくんRigidbodyですか?なんだか難しそうな名前ですね...
たなべ大丈夫、名前は難しそうだけど考え方はシンプルなんだ。
今日はRigidbodyの基本から実際の使い方まで、しっかり解説していくよ。
ゲーム開発において、物理シミュレーションは非常に重要な要素です。
ボールが転がる、キャラクターがジャンプする、敵にぶつかって跳ね返るなど、ゲームの「リアルさ」や「面白さ」を支えているのが物理演算なのです。
Unityでは、この物理シミュレーションを簡単に実現するためにRigidbodyというコンポーネントが用意されています。
Rigidbodyを使えば、複雑な計算式を自分で書かなくても、重力や衝突、力の作用といった物理現象をゲームに取り入れることができます。
この記事では、Unityの物理シミュレーションの基礎となるRigidbodyの概念と使い方について、初心者の方でも理解できるよう丁寧に解説していきます。
Rigidbodyとは何か?物理シミュレーションの基本を理解しよう
Rigidbodyの役割
Rigidbodyとは、Unityのゲームオブジェクトに「物理的な性質」を持たせるためのコンポーネントです。
日本語に訳すと「剛体」という意味になります。
剛体とは、力を加えても形が変わらない理想的な物体のことです。
ゲームでいえば、ボールやキャラクター、車など、形を保ったまま動くオブジェクトをイメージしてください。
Rigidbodyをオブジェクトに追加すると、以下のような物理的な振る舞いが自動的に適用されます。
- 重力の影響を受ける → オブジェクトが下に落ちる
- 力を加えて動かせる → 押したり、投げたりできる
- 他のオブジェクトと衝突する → ぶつかって跳ね返る、止まる
なぜRigidbodyが必要なのか
「オブジェクトを動かすだけなら、Transform.positionを直接変更すればいいのでは?」と思う方もいるかもしれません。
確かに、Transformを直接操作することでオブジェクトを移動させることは可能です。
しかし、この方法では物理的な整合性が取れないという問題があります。
例えば、Transformで直接移動させた場合、壁をすり抜けてしまったり、衝突判定が正しく行われなかったりします。
Rigidbodyを使えば、Unityの物理エンジンがこれらの計算を自動的に行ってくれるため、自然で違和感のない動きを実現できるのです。
物理シミュレーションの仕組み
UnityはPhysX(NVIDIA製の物理エンジン)を内部で使用しており、Rigidbodyを持つオブジェクトに対して以下の処理を行っています。
- 力と速度の計算 → 重力や外部からの力を計算
- 位置と回転の更新 → 計算結果に基づいてオブジェクトを移動
- 衝突検出と応答 → 他のオブジェクトとの接触を検出し、反応を計算
これらの処理はFixedUpdateというタイミングで一定間隔(デフォルトは0.02秒ごと)に実行されます。
通常のUpdate(フレームごと)とは異なるタイミングで処理されるため、物理演算は安定した結果を得られるようになっています。
Rigidbodyの追加方法と基本設定
Rigidbodyをオブジェクトに追加する
Rigidbodyの追加方法はとてもシンプルです。
- Hierarchyウィンドウで対象のオブジェクトを選択
- Inspectorウィンドウで「Add Component」をクリック
- 検索欄に「Rigidbody」と入力して選択
これだけで、オブジェクトに物理的な性質が付与されます。
3Dオブジェクトには「Rigidbody」、2Dオブジェクトには「Rigidbody2D」を使用します。
Rigidbodyの主要なプロパティ
Rigidbodyを追加すると、Inspectorにいくつかのプロパティが表示されます。
初心者が最初に理解しておくべき重要なプロパティを紹介します。
-
Mass(質量) → オブジェクトの重さを設定します。単位はキログラムです。質量が大きいほど、同じ力を加えても動きにくくなります。
-
Drag(抵抗) → 空気抵抗のような減速効果を設定します。値が大きいほど、オブジェクトは早く減速します。
-
Angular Drag(回転抵抗) → 回転に対する抵抗です。値が大きいほど、回転が早く止まります。
-
Use Gravity(重力を使用) → チェックを入れると、オブジェクトが重力の影響を受けます。
-
Is Kinematic(キネマティック) → チェックを入れると、物理演算の影響を受けなくなります。スクリプトやアニメーションで直接制御したい場合に使用します。
Colliderとの組み合わせ
Rigidbodyだけでは衝突判定は行われません。
衝突を検出するためには、Collider(コライダー)というコンポーネントも必要です。
Colliderはオブジェクトの「当たり判定の形状」を定義するもので、以下のような種類があります。
- Box Collider → 箱型の当たり判定
- Sphere Collider → 球型の当たり判定
- Capsule Collider → カプセル型の当たり判定
- Mesh Collider → メッシュ形状に沿った当たり判定
基本的なプリミティブオブジェクト(Cube、Sphereなど)を作成すると、自動的に対応するColliderが追加されます。
RigidbodyとColliderの両方がそろって初めて、物理的な衝突が機能するということを覚えておきましょう。
サンプルコードで学ぶRigidbodyの基本操作
リンドくん設定はわかりましたが、実際にスクリプトからRigidbodyを操作するにはどうすればいいんですか?
たなべいい質問だね!
Rigidbodyはスクリプトから力を加えたり、速度を変更したりできるんだ。具体的なコードを見ていこう。
力を加えて動かす(AddForce)
最も基本的な操作は、オブジェクトに力を加えることです。
以下のサンプルコードでは、ゲーム開始時にオブジェクトが上にジャンプします。
using UnityEngine;
public class JumpController : MonoBehaviour
{
// Rigidbodyコンポーネントの参照
private Rigidbody rb;
// ジャンプの力
public float jumpForce = 5f;
void Start()
{
// Rigidbodyコンポーネントを取得
rb = GetComponent<Rigidbody>();
// 上方向に力を加える
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}AddForceメソッドは、指定した方向と大きさの力をオブジェクトに加えます。
第二引数のForceModeには以下の種類があります。
- Force → 継続的な力(質量を考慮)
- Impulse → 瞬間的な力(質量を考慮)
- Acceleration → 加速度(質量を無視)
- VelocityChange → 速度の直接変更(質量を無視)
ジャンプのような瞬間的な動きにはImpulse、ロケットの推進力のような継続的な力にはForceを使うのが一般的です。
速度を直接設定する
力ではなく、速度を直接設定することも可能です。
using UnityEngine;
public class MoveController : MonoBehaviour
{
private Rigidbody rb;
public float moveSpeed = 5f;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
// 移動方向を計算
Vector3 movement = new Vector3(0.1f, 0f, 0.1f);
// 速度を設定(Y軸の速度は維持)
rb.velocity = new Vector3(
movement.x * moveSpeed,
rb.velocity.y,
movement.z * moveSpeed
);
}
}ここで重要なのは、物理演算に関するコードはFixedUpdate内に書くという点です。
Updateはフレームレートによって呼び出し頻度が変わりますが、FixedUpdateは一定間隔で呼び出されるため、物理演算が安定します。
衝突を検出する
オブジェクト同士がぶつかったときに処理を行いたい場合は、OnCollision系のメソッドを使用します。
using UnityEngine;
public class CollisionDetector : MonoBehaviour
{
// 衝突が開始したとき
void OnCollisionEnter(Collision collision)
{
Debug.Log("衝突しました: " + collision.gameObject.name);
// 特定のタグを持つオブジェクトと衝突した場合
if (collision.gameObject.CompareTag("Enemy"))
{
Debug.Log("敵に接触!");
}
}
// 衝突している間
void OnCollisionStay(Collision collision)
{
Debug.Log("接触中: " + collision.gameObject.name);
}
// 衝突が終了したとき
void OnCollisionExit(Collision collision)
{
Debug.Log("離れました: " + collision.gameObject.name);
}
}衝突検出が機能するためには、両方のオブジェクトにColliderがあり、少なくとも一方にRigidbodyがある必要があります。
Rigidbodyを使う際の注意点とベストプラクティス
Transform.positionの直接変更を避ける
Rigidbodyを持つオブジェクトのTransformを直接操作すると、物理演算と干渉して予期しない動作を引き起こすことがあります。
// 非推奨
transform.position = new Vector3(0, 5, 0);
// 推奨
rb.MovePosition(new Vector3(0, 5, 0));位置を直接変更したい場合は、MovePositionメソッドを使用しましょう。
パフォーマンスへの配慮
Rigidbodyは物理演算を行うため、大量に使用するとパフォーマンスに影響します。
以下の点に注意しましょう。
- 動かないオブジェクトにはRigidbodyを追加しない(Colliderのみで十分)
- 動かなくなったオブジェクトは
rb.Sleep()で休止状態にする - 不要になったRigidbodyは無効化または削除する
Kinematicの適切な使用
Is Kinematicをオンにすると、そのRigidbodyは物理演算の影響を受けなくなります。
これは以下のような場合に便利です。
- アニメーションで動かすキャラクター
- プレイヤーが直接制御するオブジェクト
- 移動するプラットフォーム
ただし、Kinematicなオブジェクト同士は衝突しないため、用途に応じて使い分けることが重要です。
まとめ
リンドくんなるほど!Rigidbodyって思ったより奥が深いんですね。でも基本的な使い方はわかりました!
たなべその通り!最初は基本をしっかり押さえることが大切なんだ。
あとは実際に色々なゲームを作りながら、経験を積んでいこう。
今回は、UnityのRigidbodyと物理シミュレーションの基礎について解説しました。
ここまでの重要なポイントを整理しておきましょう。
Rigidbodyの基本的な考え方
- Rigidbodyはオブジェクトに物理的な性質を与えるコンポーネント
- 重力、衝突、力の作用といった物理現象を自動的に計算してくれる
- 衝突判定にはColliderとの組み合わせが必須
スクリプトでの操作方法
- AddForceで力を加えてオブジェクトを動かす
- velocityで速度を直接設定することも可能
- 物理演算のコードはFixedUpdate内に書く
注意すべきポイント
- Transformの直接操作は避け、MovePositionなどを使用する
- パフォーマンスを意識して、不要なRigidbodyは使わない
- Is Kinematicの使いどころを理解する
物理シミュレーションは、ゲームに「リアルさ」と「楽しさ」を加える重要な要素です。
最初は難しく感じるかもしれませんが、実際に手を動かしながら試していくことで、徐々に理解が深まっていきます。
ぜひ今回学んだ内容を活かして、ボールを転がしたり、キャラクターをジャンプさせたり、さまざまな物理表現に挑戦してみてください。
Unityの物理シミュレーションをマスターすれば、ゲーム開発の幅が大きく広がるはずです。





