概要
Unityの強力な機能の一つに、リアルな物理シミュレーションを簡単に行える物理エンジン (NVIDIA PhysX) があります。オブジェクトが重力で落下したり、力が加わると加速したり、オブジェクト同士が衝突して跳ね返ったりといった、現実世界のような挙動は、すべてこの物理エンジンが計算しています。
そして、ゲームオブジェクトをこの物理エンジンの管理下に置き、「物理法則に従う物体」として振る舞わせるためのコンポーネントが Rigidbody(リジッドボディ/剛体) です。Transformコンポーネントを直接操作してオブジェクトを動かすのとは異なり、Rigidbodyを使うことで、よりリアルでダイナミックな動きを実現できます。
この記事では、Rigidbodyコンポーネントの基本的な役割と、Rigidbodyを使ってオブジェクトを正しく動かすための方法について詳しく解説します。
Rigidbodyの役割
ゲームオブジェクトにRigidbodyコンポーネントを追加すると、そのオブジェクトは「質量を持つ物体」として扱われるようになり、以下のような物理的な影響を受けるようになります。
- 重力:
Use Gravityがオンの場合、オブジェクトは自動的に重力(デフォルトではY軸のマイナス方向)に引かれて落下します。 - 力とトルク: スクリプトから
AddForceで力を加えれば加速し、AddTorqueでトルク(回転力)を加えれば回転します。 - 衝突: 他の
RigidbodyやColliderを持つオブジェクトと衝突し、質量や速度に応じてリアルな反発や押し出しが発生します。 - 抗力:
Drag(空気抵抗)やAngular Drag(回転の抵抗)を設定することで、動きの減衰を表現できます。
transform vs Rigidbody: オブジェクトの動かし方
初心者が最も混乱しやすいのが、transform.Translate()で動かす方法と、Rigidbodyを使って動かす方法の違いです。
-
transform.Translate(): オブジェクトを現在の位置から指定した分だけ「ワープ」させるようなものです。物理法則を完全に無視するため、壁にめり込んだり、他のオブジェクトをすり抜けたりすることがあります。物理的なインタラクションを必要としない、単純な動きや、物理エンジンの管理外に置きたいオブジェクト(例: カメラの移動)に適しています。 -
Rigidbodyの操作: オブジェクトに力を加えたり、速度を直接設定したりして動かします。すべての動きは物理エンジンによって計算・管理されるため、他のオブジェクトとの間でリアルな衝突やインタラクションが発生します。物理的な挙動をさせたいオブジェクトは、必ずRigidbody経由で動かすべきです。
警告: Rigidbodyを持つオブジェクトのtransformを直接操作すると、物理エンジンの計算と矛盾が生じ、テレポートや不自然な衝突など、予期せぬ挙動の原因となります。両者を混在させるのは避けましょう。
Rigidbodyを使ったオブジェクトの動かし方
Rigidbodyを操作するには、まずGetComponent<Rigidbody>()でその参照を取得し、FixedUpdate()内で処理を行うのが基本です。
1. AddForce()で力を加える
AddForce()は、オブジェクトに継続的に力を加え、加速させるた めの最も一般的な方法です。現実世界の「押す」力に近いです。
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class PlayerController : MonoBehaviour
{
public float moveForce = 10f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
// Rigidbodyに力を加える
rb.AddForce(movement * moveForce);
}
}
AddForceには、力の加え方を指定するForceModeというオプション引数があります。
ForceMode.Force: 質量を考慮した継続的な力を加える(デフォルト)。ForceMode.Acceleration: 質量を無視した継続的な力を加える。ForceMode.Impulse: 質量を考慮した瞬間的な撃力(爆発など)を加える。ForceMode.VelocityChange: 質量を無視した瞬間的な速度変化を加える。
2. velocityで速度を直接設定する
rb.velocityプロパティを直接変更することで、オブジェクトの速度を即座に設定することもできます。より直接的で、キビキビとした操作感のキャラクターコントロールを実装したい場合に便利です。
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
// 現在のY軸方向の速度を維持しつつ、X,Z軸の速度を設定
rb.velocity = new Vector3(movement.x * speed, rb.velocity.y, movement.z * speed);
}
重要なプロパティ
- Mass: オブジェクトの質量。重いほど動きにくく、他のオブジェクトに与える影響が大きくなります。
- Drag: 移動時の空気抵抗。値が大きいほど、すぐに速度が減衰します。
- Angular Drag: 回転時の抵抗。値が大きいほど、回転がすぐに止まります。
- Use Gravity: 重力の影響を受けるかどうか。
- Is Kinematic: これをオンにすると、オブジェクトは物理エンジンによる力の適用(重力や衝突など)を受け付けなくなります。ただし、
transformを動かすことで他のRigidbody(Is Kinematicがオフのもの)に対しては物理的な影響(押し出しなど)を与えることができます。アニメーションで動くキャラクターや、スクリプトで厳密に制御したいプラットフォームなどに使われます。 - Constraints: 特定の軸方向への移動や回転を凍結(ロック)できます。例えば、2DゲームのキャラクターがZ軸に動かないようにしたり、プレイヤーキャラクターが転倒しないようにX,Z軸の回転を凍結したりするのに使います。
まとめ
Rigidbodyは、Unityの物理演算世界の主役です。
Rigidbodyを追加すると、オブジェクトは物理法則に従うようになる。- 物理的な挙動をさせたいオブジェクトは、
transformではなくRigidbodyを操作して動かす。 - 継続的な力は
AddForce()、直接的な速度制御はvelocityで行う。 - 処理は
FixedUpdate()内に記述す るのが鉄則。 Is Kinematicは、物理演算を受けずに影響だけを与える特殊なモード。
Rigidbodyを正しく使いこなすことが、リアルで説得力のあるインタラクションを生み出す鍵となります。