Rigidbody
Rigidbody は GameObject を物理エンジンに委ねます——重力・力・速度・衝突は Update ではなく Unity Physics が計算します。質量、ForceMode、isKinematic、AddForce の使い分けを学び、安定した物理駆動を身につけられます。図解で力を体感できます。
想像してみてください...
Rigidbody は物体の物理の魂のようなものです。加える前、箱は空中に浮いた静止画にすぎません。 Rigidbody を付けると質量を持つ剛体になり——重力で落ち、衝突で弾み、力で滑ります。 `transform.position` を直接書く代わりに、`AddForce()` で手で押すように動かします。
概念の詳細
Rigidbody は GameObject を Unity Physics に登録します。
主なプロパティ:mass(kg)、drag(空気抵抗)、
angularDrag(回転抵抗)、useGravity、
isKinematic。
ForceMode: Force(連続、質量を考慮)、
Acceleration(連続、質量無視)、Impulse(瞬間、質量を考慮 —
ジャンプに典型)、VelocityChange(瞬間、質量無視)。
Kinematic Rigidbody:
isKinematic = true — 衝突検知には参加するが、力や重力では動かない。
MovePosition() で動かします。移動床やアニメーション駆動の物体向けです。
重要ルール: 非 kinematic の Rigidbody に
transform.position を直接設定しないでください——テレポートしてシミュレーションが壊れます。
必ず AddForce() か velocity を使います。
ダイアグラム:力と ForceMode
ForceMode Types
Force
連続、質量を考慮。ロケット、風など
rb.AddForce(dir * 10f)Impulse
瞬間、質量を考慮。ジャンプ、爆発ノックバック
rb.AddForce(Vector3.up * 5f, ForceMode.Impulse)VelocityChange
瞬間、質量を無視。速度を直接設定
rb.AddForce(dir, ForceMode.VelocityChange)Rigidbody Properties
Constraints (Freeze)
ハンズオン手順
Rigidbody コンポーネントを追加
Inspector → Add Component → Physics → Rigidbody。衝突が必要なら Collider も追加します。
Awake で Rigidbody をキャッシュ
_rb = GetComponent<Rigidbody>() — その後 FixedUpdate で使います。
FixedUpdate で力によって動かす
transform.position を書かないでください。AddForce() か velocity を使います。
2D トップダウンでは Freeze Rotation
Inspector → Constraints → Freeze Rotation X, Y, Z で衝突時に転がらないようにします。
移動床には isKinematic を使う
アニメーション駆動の床 → isKinematic = true + MovePosition()。
インタラクティブシミュレーター
キャンバスをクリックして物体を生成。Gravity、Mass、Drag を調整し、Force Up でインパルスを加えましょう。
コード例
基本Rigidbody で移動とジャンプ。
using UnityEngine;
public class PhysicsPlayer : MonoBehaviour
{
[SerializeField] private float moveForce = 10f;
[SerializeField] private float jumpForce = 7f;
[SerializeField] private float maxSpeed = 8f;
private Rigidbody _rb;
private Vector3 _input;
private bool _grounded;
void Awake() => _rb = GetComponent<Rigidbody>();
void Update()
{
_input = new Vector3(Input.GetAxisRaw("Horizontal"), 0,
Input.GetAxisRaw("Vertical"));
if (Input.GetButtonDown("Jump") && _grounded)
_rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
void FixedUpdate()
{
// Cap speed on the horizontal plane
Vector3 flatVel = new Vector3(_rb.velocity.x, 0f, _rb.velocity.z);
if (flatVel.magnitude > maxSpeed)
_rb.velocity = flatVel.normalized * maxSpeed + Vector3.up * _rb.velocity.y;
_rb.AddForce(_input.normalized * moveForce, ForceMode.Force);
}
private void OnCollisionEnter(Collision col)
=> _grounded = col.gameObject.CompareTag("Ground");
private void OnCollisionExit(Collision col)
=> _grounded = false;
}コード例
上級AddExplosionForce で爆風——中心から剛体を吹き飛ばす。
using UnityEngine;
public class Explosion : MonoBehaviour
{
[SerializeField] private float force = 500f;
[SerializeField] private float radius = 5f;
[SerializeField] private float upModifier = 0.5f;
public void Explode()
{
// Find every Collider inside the radius
Collider[] cols = Physics.OverlapSphere(transform.position, radius);
foreach (var col in cols)
{
var rb = col.GetComponent<Rigidbody>();
if (rb == null) continue;
// Unity scales the force by distance
rb.AddExplosionForce(force, transform.position, radius, upModifier);
}
// Visual effect + destroy
GetComponent<ParticleSystem>()?.Play();
Destroy(gameObject, 2f);
}
}📌 要点
- ▸力 → FixedUpdate;入力 → Update
- ▸ジャンプ:
AddForce(up, ForceMode.Impulse) - ▸非 kinematic RB に
transform.positionを設定しない - ▸移動床 → isKinematic + MovePosition
⚠️ よくあるミス
❌ Rigidbody に transform.position を書く
テレポート——物理が壊れ、壁抜けや衝突の不具合
✅ rb.MovePosition() か velocity
❌ 物理コードを Update に書く(FixedUpdate ではない)
物理タイムステップとずれ → ジッター、トンネリング
✅ AddForce / velocity の呼び出しはすべて FixedUpdate