キャラクターを動かしたら壁にめり込んだ。弾を速くしたら壁をすり抜けた。移動を書き換えたらガクガク震え出した——物理まわりのトラブルは、だいたい「物理エンジンの流儀」を知らずにtransformと物理を混ぜてしまったときに起きます。
その流儀の中心にいるのが Rigidbody(リジッドボディ/剛体) です。ゲームオブジェクトをUnityの 物理エンジン(NVIDIA PhysX) の管理下に置き、「物理法則に従う物体」として振る舞わせるコンポーネントです。この記事では、Rigidbodyの役割とtransformとの正しい使い分け、力と速度によるオブジェクトの動かし方を解説します。
この記事でわかること
Rigidbodyを付けると何が起きるのか(重力・力・衝突・抗力)transform操作とRigidbody操作の決定的な違いAddForceとlinearVelocityの使い分けとForceMode4種Is Kinematic・Constraintsなど重要プロパティ の実務的な使いどころ- Unity 6でのAPI名の変更(
velocity→linearVelocityなど)
Rigidbodyの役割
ゲームオブジェクトにRigidbodyコンポーネントを追加すると、そのオブジェクトは「質量を持つ物体」として扱われるようになり、以下のような物理的な影響を受けるようになります。
- 重力:
Use Gravityがオンの場合、オブジェクトは自動的に重力(デフォルトではY軸のマイナス方向)に引かれて落下します。 - 力とトルク: スクリプトから
AddForceで力を加えれば加速し、AddTorqueでトルク(回転力)を加えれば回転します。 - 衝突: 他の
RigidbodyやColliderを持つオブジェクトと衝突し、質量や速度に応じてリアルな反発や押し出しが発生します。 - 抗力:
Linear Damping(移動の減衰)やAngular Damping(回転の減衰)を設定することで、動きの減衰を表現できます。
補足(Unity 6での名称変更): この2つは以前は
Drag/Angular Dragという名前でした。Unity 6(2023.3以降)でインスペクター表記・API名ともLinear Damping(linearDamping)/Angular Damping(angularDamping)に変わっています。他の変更は Unity 6 新旧API読み替えガイド を参照してください。
transform vs Rigidbody: オブジェクトの動かし方
初心者が最も混乱しやすいのが、transform.Translate()で動かす方法と、Rigidbodyを使って動かす方法の違いです。ひとことで言えば、「ワープ」か「物理移動」かの違いです。

-
transform.Translate(): オブジェクトを現在の位置から指定した分だけ「ワープ」させるようなものです。物理法則を完全に無視するため、壁にめり込んだり、他のオブジェクトをすり抜けたりすることがあります。物理的なインタラクションを必要としない、単純な動きや、物理エンジンの管理外に置きた いオブジェクト(例: カメラの移動)に適しています。 -
Rigidbodyの操作: オブジェクトに力を加えたり、速度を直接設定したりして動かします。すべての動きは物理エンジンによって計算・管理されるため、他のオブジェクトとの間でリアルな衝突やインタラクションが発生します。物理的な挙動をさせたいオブジェクトは、必ずRigidbody経由で動かすべきです。
警告:
Rigidbodyを持つオブジェクトのtransformを直接操作すると、物理エンジンの計算と矛盾が生じ、テレポートや不自然な衝突など、予期せぬ挙動の原因となります。冒頭の「めり込み」「震え」の多くはこの混在が原因です。両者を混ぜないようにしましょう。
Rigidbodyを使ったオブジェクトの動かし方
Rigidbodyを操作するには、まずGetComponent<Rigidbody>()でその参照を取得し、FixedUpdate()内で処理を行うのが基本です。物理エンジンは描画(Update)とは別の一定リズムで動いているため、物理操作もそのリズムに合わせる必要があるからです。ただし 入力の読み取りだけはUpdate()で行い、保存した値をFixedUpdate()で使います(FixedUpdateで読む と入力を取りこぼすため。詳しくは UpdateとFixedUpdateの記事 を参照)。
1. AddForce()で力を加える
AddForce()は、オブジェクトに継続的に力を加え、加速させるための最も一般的な方法です。現実世界の「押す」力に近く、慣性のあるリアルな動きになります。
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class PlayerController : MonoBehaviour
{
public float moveForce = 10f;
private Rigidbody rb;
private Vector3 moveInput;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
// 入力の読み取りはUpdateで行い、変数に保存しておく
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
// 斜め入力で速くならないよう、ベクトルの長さを1以下に抑える
moveInput = Vector3.ClampMagnitude(
new Vector3(moveHorizontal, 0.0f, moveVertical), 1f);
}
void FixedUpdate()
{
// 保存した入力を使い、物理更新のリズムで力を加える
rb.AddForce(moveInput * moveForce);
}
}
小さなポイントが2つ入っています。1つは 入力をUpdateで読んでFixedUpdateで使う 分担(物理移動の基本形)。もう1つはVector3.ClampMagnitudeです。斜め入力では(1, 0, 1)のように長さが約1.4のベクトルになるため、そのまま使うと 斜め移動だけ1.4倍速くなる 定番バグが生まれます。長さを1以下に丸めておけば全方向が同じ速さになります。
AddForceには、力の加え方を指定するForceModeというオプション引数があります。 「継続か、瞬間か」×「質量を考慮するか、しないか」 の組み合わせで4種類です。

ForceMode.Force: 質量を考慮した継続的な力(デフォルト)。エンジンの推進力などForceMode.Acceleration: 質量を無視した継続的な力。重さに関係なく同じ加速をさせたいときForceMode.Impulse: 質量を考慮した瞬間的な撃力。ジャンプ、爆発、バットで打つForceMode.VelocityChange: 質量を無視した瞬間的な速度変化。ノックバックの距離を揃えたいときなど
迷ったら、押し続けるならForce、一発ならImpulse と覚えておけば大半のケースをカバーできます。
2. linearVelocityで速度を直接設定する
rb.linearVelocityプロパティを直接変更することで、オブジェクトの速度を即座に設定できます。加速を待たずに狙った速度で動き出すため、キビキビとした操作感のキャラクターコントロールを実装したい場合に便利です。
private Vector3 moveInput;
void Update()
{
// ここでも「Updateで読んでFixedUpdateで使う」分担は同じ
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
moveInput = Vector3.ClampMagnitude(
new Vector3(moveHorizontal, 0.0f, moveVertical), 1f);
}
void FixedUpdate()
{
// 現在のY軸方向の速度(落下など)を維持しつつ、X,Z軸の速度を設定
rb.linearVelocity = new Vector3(moveInput.x * speed, rb.linearVelocity.y, moveInput.z * speed);
}
補足(旧APIとの読み替え): このプロパティは以前は
rb.velocityでした。Unity 6ではlinearVelocityに改名されています(古いチュートリアルのコードを写して警告が出たら、これが原因です)。
使い分けの判断基準は1行です。 「物理らしい慣性が欲しいか、手に吸い付く操作感が欲しいか」 ——前者ならAddForce、後者ならlinearVelocityです。
重要なプロパティ
- Mass: オブジェクトの質量。重いほど動きにくく、衝突時に他へ与える影響が大きくなります。
- Linear Damping: 移動の減衰(旧: Drag)。値が大きいほど、すぐに速度が落ちます。
- Angular Damping: 回転の減衰(旧: Angular Drag)。値が大きいほど、回転がす ぐに止まります。
- Use Gravity: 重力の影響を受けるかどうか。
- Is Kinematic: オンにすると、オブジェクトは物理エンジンによる力の適用(重力や衝突の反発など)を受け付けなくなります。ただし、
transformやアニメーションで動かせば、他のRigidbody(Is Kinematicがオフのもの)を押すことはできます。アニメーションで動くキャラクターや、スクリプトで厳密に制御したい移動床などに使われます。 - Constraints: 特定の軸方向への移動や回転を凍結(ロック)できます。

Constraintsの定番はキャラクターの転倒防止です。カプセル型のキャラクターは衝突のはずみでコロンと倒れてしまうため、Freeze RotationのX・Zを凍結して直立を保つのが定石です。2DライクなゲームでFreeze Position Zを使うのもよくあるパターンです。
おまけ:先に知っておくと良いこと
物理で動くようになったら、次はこのあたりのトラブル対策が視野に入ってきます。
- 高速な弾がすり抜ける → Collision Detection: 物理は一定間隔の「コマ送り」で計算されるため、速すぎる物体は1コマの間に壁を通り過ぎて しまいます。Rigidbodyの Collision Detection を
Continuous(動く側)やContinuous Dynamicに変更すると、コマの間の移動経路まで判定してくれます。 - 動きがカクつく → Interpolate: 物理の更新(FixedUpdate)は描画(Update)よりも回数が少ないため、物理で動くオブジェクトをカメラで追うとカクつくことがあります。Rigidbodyの Interpolate を
Interpolateに設定すると、描画フレームに合わせて位置が補間され、滑らかになります。 - 衝突を検知して処理したい: ぶつかった瞬間にダメージを与える・アイテムを取るといった処理は、
OnCollisionEnter/OnTriggerEnterで受け取ります。OnTriggerとOnCollisionの記事 で整理しています。 - 2Dゲームの場合: 2Dには専用の
Rigidbody2D/Collider2Dがあります(3D用と混ぜると衝突しません)。Rigidbody2DとCollider2Dの記事 を参照してください。
まとめ
Rigidbodyは、Unityの物理演算世界の主役です。
Rigidbodyを追加すると、オブジェクトは物理法則に従うようになる。- 物理的な挙動をさせたいオブジェクトは、
transformではなくRigidbodyを操作して動かす。 混ぜるとめり込み・すり抜け・震えの原因になる。 - 継続的な力は
AddForce()、直接的な速度制御はlinearVelocity(旧velocity)。ForceModeは「継続か瞬間か×質量を考慮するか」で4種類。 - 物理操作は
FixedUpdate()、入力の読み取りはUpdate()。 「Updateで読んでFixedUpdateで使う」が基本形。 Is Kinematicは力を受けずに影響だけ与えるモード、Constraintsは転倒防止などの軸ロック。
Rigidbodyを正しく使いこなすことが、リアルで説得力のあるインタラクションを生み出す鍵となります。