Unity Term Book
物理

Rigidbody

Rigidbody は GameObject を物理エンジンに委ねます——重力・力・速度・衝突は Update ではなく Unity Physics が計算します。質量、ForceMode、isKinematic、AddForce の使い分けを学び、安定した物理駆動を身につけられます。図解で力を体感できます。

想像してみてください...

Rigidbody は物体の物理の魂のようなものです。加える前、箱は空中に浮いた静止画にすぎません。 Rigidbody を付けると質量を持つ剛体になり——重力で落ち、衝突で弾み、力で滑ります。 `transform.position` を直接書く代わりに、`AddForce()` で手で押すように動かします。

概念の詳細

Rigidbody は GameObject を Unity Physics に登録します。 主なプロパティ:mass(kg)、drag(空気抵抗)、 angularDrag(回転抵抗)、useGravityisKinematic

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

mass1.0 kg
drag0.0
angularDrag0.05
useGravitytrue
isKinematicfalse

Constraints (Freeze)

☑ Freeze Pos X☑ Freeze Rot Z□ Freeze Pos Y□ Freeze Rot X

ハンズオン手順

1

Rigidbody コンポーネントを追加

Inspector → Add Component → Physics → Rigidbody。衝突が必要なら Collider も追加します。

2

Awake で Rigidbody をキャッシュ

_rb = GetComponent<Rigidbody>() — その後 FixedUpdate で使います。

3

FixedUpdate で力によって動かす

transform.position を書かないでください。AddForce()velocity を使います。

4

2D トップダウンでは Freeze Rotation

Inspector → Constraints → Freeze Rotation X, Y, Z で衝突時に転がらないようにします。

5

移動床には isKinematic を使う

アニメーション駆動の床 → isKinematic = true + MovePosition()

インタラクティブシミュレーター

キャンバスをクリックして物体を生成。Gravity、Mass、Drag を調整し、Force Up でインパルスを加えましょう。

Objects: 0|Gravity: 9.8 m/s²|キャンバスをクリックして Rigidbody を生成

コード例

基本

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