こんにちは!夜の街2Dアクションゲームを制作中の怪獣です🦖
Unity2Dでプレイヤーをジャンプさせたいけど、
- ジャンプのさせ方が分からない
- ジャンプが高くなりすぎる
- 連続ジャンプしてしまう
- 地面判定がうまくいかない
といった悩みはありませんか?
この記事では、Rigidbody2Dを使ったジャンプ実装方法を、
初心者向けにわかりやすく解説します!
①今回の完成イメージ
- スペースキー(または Input System のJump)でジャンプ
- 地面にいる時だけジャンプ可能(空中連打で多段ジャンプしない)
- Rigidbody2D を使用
- 接地判定は BoxCast で足元をチェック
②事前準備
プレイヤー、プレイヤーが立てる床のオブジェクトを用意しておきます。
プレイヤー側
Rigidbody2DCollider2D(BoxCollider2Dなど)
床側
Collider2D(BoxCollider2D / TilemapCollider2Dなど)- 床を「Ground用のLayer(例:Floor)」に設定
※今回の判定は Tagではなく LayerMask を使います。
「Floorレイヤーのものだけ地面扱い」になるので、誤判定が減ります。
③ジャンプ処理の基本コード
✅ Input System の Jump を呼ぶ前提で _OnJump() を用意しています。
旧Input(Input.GetKeyDown)版も後半で紹介します。
public class Player : MonoBehaviour
{
[SerializeField, Header("ジャンプ速度")]
private float _jumpSpeed;
[SerializeField, Header("接地判定用レイヤー(Floorなど)")]
private LayerMask _groundMask; // インスペクターでFloorを指定
private Rigidbody2D _rigid;
private bool _bJump;
private Collider2D _col; // 実寸取得用
void Start()
{
_rigid = GetComponent<Rigidbody2D>();
_col = GetComponent<Collider2D>();
_bJump = false;
}
void Update()
{
_HitFloor();
}
// 今床に触れているか、空中状態か判定する
private void _HitFloor()
{
// もしプレイヤーのColliderが存在しなければ処理しない
if (_col == null) return;
// 接地判定のためのBoxCast(四角形の当たり判定を下に飛ばす)を準備する
// プレイヤーのコライダーの範囲を取得
Bounds b = _col.bounds;
// 判定を出す位置(プレイヤーの足元より少し下に設定)
Vector2 center = new Vector2(b.center.x, b.min.y - 0.05f);
// 判定の大きさ(横幅はキャラより少し小さめ、高さはごく薄い矩形)
Vector2 size = new Vector2(b.size.x * 0.9f, 0.12f);
// BoxCastを実行
// ・center:判定の中心位置
// ・size :判定の大きさ
// ・0f :角度は回転なし
// ・Vector2.down:真下に向けて判定
// ・0.05f :判定を飛ばす長さ(わずかに下へ伸ばす)
// ・_groundMask:Floorなど「地面」とするレイヤーにだけ反応させる
RaycastHit2D hit = Physics2D.BoxCast(center, size, 0f, Vector2.down, 0.05f, _groundMask);
// 当たり判定の情報取得
bool grounded = (hit.collider != null);
// 地面と触れたか確認
if (grounded)
{
// 地面にいる → ジャンプ可能
_bJump = false;
}
else
{
// 空中にいる → ジャンプ不可
_bJump = true;
}
}
// ジャンプ処理
public void _OnJump(InputAction.CallbackContext context)
{
// 押下(performed)でなければ無視 / 空中なら無視
if (!context.performed || _bJump) return;
// Impulse:初速が早く徐々に減速、Force:初速が遅く、徐々に加速
_rigid.AddForce(Vector2.up * _jumpSpeed, ForceMode2D.Impulse);
// 連打での多段を防ぐために即座に空中扱い
_bJump = true;
}
}④各処理の解説(初心者向け)
フィールド変数の追加
[SerializeField, Header("接地判定用レイヤー(Floorなど)")]
private LayerMask _groundMask; // インスペクターでFloorを指定
private Rigidbody2D _rigid;
private bool _bJump;
private Collider2D _col; // 実寸取得用
_jumpSpeed:ジャンプの強さ(大きいほど高く跳ぶ)_groundMask:「床」と判定するレイヤーを指定します。(Floorなど)インスペクターで Floor レイヤーを選んでください。
✅ Tag判定よりLayer判定の方が、Tilemapや複数床でも管理しやすいです。
Start(必要コンポーネントを取得)
void Start()
{
_rigid = GetComponent<Rigidbody2D>();
_col = GetComponent<Collider2D>();
_bJump = false;
}
Collider2D(プレイヤー自身に付いている当たり判定情報)を取得して変数に保存。_bJumpは「今ジャンプ中かどうか」を管理するフラグです。初期値はfalse(ジャンプ可能)。
Update(接地状態を更新)
void Update()
{
_HitFloor(); // 接地状態をチェック
}
Updateは毎フレーム呼び出されるUnityの共通機能です。
ここで _HitFloor() を呼び出して、接地中かどうかを更新します。
_HitFloor (BoxCastで接地判定する)
今床に触れているか、空中状態か判定するメソッドを作成します。
床に触れている場合はジャンプ可能、空中の場合はジャンプ不可能に制御します📝
// 今床に触れているか、空中状態か判定する
private void _HitFloor()
{
// もしプレイヤーのColliderが存在しなければ処理しない
if (_col == null) return;
// 接地判定のためのBoxCast(四角形の当たり判定を下に飛ばす)を準備する
// プレイヤーのコライダーの範囲を取得
Bounds b = _col.bounds;
// 判定を出す位置(プレイヤーの足元より少し下に設定)
Vector2 center = new Vector2(b.center.x, b.min.y - 0.05f);
// 判定の大きさ(横幅はキャラより少し小さめ、高さはごく薄い矩形)
Vector2 size = new Vector2(b.size.x * 0.9f, 0.12f);
// BoxCastを実行
// ・center:判定の中心位置
// ・size :判定の大きさ
// ・0f :角度は回転なし
// ・Vector2.down:真下に向けて判定
// ・0.05f :判定を飛ばす長さ(わずかに下へ伸ばす)
// ・_groundMask:Floorなど「地面」とするレイヤーにだけ反応させる
RaycastHit2D hit = Physics2D.BoxCast(center, size, 0f, Vector2.down, 0.05f, _groundMask);
// 当たり判定の情報取得
bool grounded = (hit.collider != null);
// 地面と触れたか確認
if (grounded)
{
// 地面にいる → ジャンプ可能
_bJump = false;
}
else
{
// 空中にいる → ジャンプ不可
_bJump = true;
}
}
BoxCastとは?
一言で言うと、「四角形を飛ばして、当たり判定を行う機能」です。
Unityにはいくつかの判定方法があります。
| 方法 | 形 | 用途 |
|---|---|---|
| Raycast | 線 | 足元・視線判定 |
| CircleCast | 円 | 丸いキャラ向き |
| BoxCast | 四角形 | 2Dキャラの接地判定に最適 |
なぜジャンプ判定でBoxCastを使うのか?
プレイヤーは四角いことが多いですよね。
□ ← プレイヤー
 ̄ ̄ ̄ ̄ ← 床
Raycast(線)だと、
|
|
□
 ̄ ̄ ̄ ̄
→ ちょっとズレると判定ミスします。
でも BoxCast なら:
███ ← 薄い箱
□
 ̄ ̄ ̄ ̄
足元全体をチェックできるので安定しやすいです。
- BoxCast で足元に薄い箱を飛ばし、床と接触しているかを確認する。
- BoxCastのサイズ調整
横幅を*0.9fにしているのは、左右ギリギリを避けて誤判定を減らすため。
縦の大きさを小さくして「足元の薄い判定」としています。 grounded = true→ 接地中(ジャンプできる)grounded = false→ 空中(ジャンプ禁止)
これで「空中で無限ジャンプ」を防止できます!
_OnJump (ジャンプ処理)
public void _OnJump(InputAction.CallbackContext context)
{
// 入力が押された瞬間以外は無視 / 空中中は無視
if (!context.performed || _bJump) return;
// Rigidbodyに上方向の力を加える
_rigid.AddForce(Vector2.up * _jumpSpeed, ForceMode2D.Impulse);
// ジャンプ直後は空中扱いにして多段ジャンプを防ぐ
_bJump = true;
}
context.performed… 入力が「押された瞬間」だけ反応します。_bJumpがtrueのとき(空中)は処理をスキップ。AddForceを Impulseモード で使うことで、初速を一気に与えて自然なジャンプ挙動になります。
⑤ ジャンプが高すぎる/低すぎる時の調整ポイント
_jumpSpeed を調整
8 → 6、10 などに調整
Rigidbody2D の「Gravity Scale」
重力が軽いとフワフワ、高いと重くなります。
⑥ よくあるエラーと対処法
❌ 地面にいるのにジャンプできない
- 床の Layer が
_groundMaskに含まれていない _groundMaskが「Nothing」になっている- BoxCast の
center / size / distanceが小さすぎて床に届いていない
✅ 対処:床をFloorレイヤーに設定 → Playerの_groundMaskにFloorをチェック
❌ 空中で連続ジャンプできる(多段になってしまう)
_HitFloor()が呼ばれていない/判定が機能していない- ジャンプ後
_bJump = true;を入れていない
✅ 対処:_OnJump の最後で _bJump = true; を必ず入れる
❌ 斜面や段差で接地判定がガタつく
- sizeが薄すぎる/小さすぎる
- distanceが短すぎる
✅ 対処:size.y や 0.05f を少し増やす(例:0.08f、0.1f)
⑦(任意)旧Input版(Input.GetKeyDown)での書き方
Input Systemを使っていない場合は、Updateでこう書けばOKです🙆
if (Input.GetKeyDown(KeyCode.Space) && !_bJump)
{
_rigid.AddForce(Vector2.up * _jumpSpeed, ForceMode2D.Impulse);
_bJump = true;
}今回は、Unity2Dでのジャンプ実装方法を解説しました。
最後まで読んでいただきありがとうございました。

コメント