こんにちは、Unity初心者の流です。
今回は、前回紹介したジャンプ動作に地面にいるときにしかジャンプしないよう「ジャンプの接地判定」を追加してみます。
前回の記事をまだ読んでいない方はこちらを参照してください↓
Unity初心者がゲームの動きを作ってみた1【ジャンプ動作】
今回の目次です。
- 前回までの動き
- 接地判定の作成
- スクリプトの解説
- まとめ
前回までの動き
まずは、前回の状態がどのようなものだったかを確認していきます。
Playボタンをクリックします。
Spaceキーを押すとジャンプするのですが
空中でSpaceキーを押してもジャンプしてしまいます。
Spaceキーを連打すると、ジャンプし続け画面外に出て行ってしまいます。

Spaceキーを連打すれば、するだけジャンプするというのはよくあるゲームの動きではありません。
では、どんな時にジャンプするのがいいかというと、地面にいるときにです。
そこで、今回は「プレイヤーが地面にいる」ことを確認するための接地判定を作っていきます。
接地判定の作成
接地判定を行うには、オブジェクトに当たり判定のコンポーネントが必要です。
当たり判定というのは、オブジェクトとオブジェクトが衝突しているかどうかを調べることです。
当たり判定のコンポーネントがついていないと、オブジェクトとオブジェクトが、衝突せずにすり抜けてしまいます。
ですが現状、プレイヤーは床をすり抜けることなく床の上にいます。
床の上にいるということは、もうすでに当たり判定が行われているのです。
当たり判定に使うコンポーネントはプレイヤーと床についています。
Playerオブジェクトからどれが当たり判定に使うコンポーネントなのか見ていきましょう。
HierarchyビューのPlayerオブジェクトをクリックしPlayerオブジェクトのInspectorビューを確認します。

このBox Colliderというコンポーネントがプレイヤーの当たり判定に必要なコンポーネントです。
次に、Floorオブジェクトの当たり判定に必要なコンポーネントも確認します。
Playerオブジェクトと同様に、HierarchyビューのFloorオブジェクトをクリックしFloorオブジェクトのInspectorビューを確認します。

Floorオブジェクトの場合は、Mesh Colliderが当たり判定に必要なコンポーネントです。
Box ColliderとMesh ColliderのBox・Meshというのは当たり判定を行う際の形を表しています。
Colliderは当たり判定という意味です。
ですので、Box Colliderは箱型(Box)の当たり判定(Collider)という意味になります。
実際にC#スクリプトを編集し、接地判定を作っていきます。
以下をコピペし追加してください。
//床に当たっているかどうか
private bool isFloor = false;


以下のコードへ編集してください。
if (Input.GetKeyDown(KeyCode.Space) && isFloor == true)


以下をコピペし追加してください。
//ジャンプして床から離れたので、床に当たっているかどうか(isFloor)を いいえ(false)に変更
isFloor = false;


以下をコピペし追加してください。
private void OnCollisionEnter(Collision collision)
{
//相手の名前を取得
string name = collision.gameObject.name;
//相手の名前が、Floorだった時
if (name == "Floor")
{
//床に当たっているので、床に当たっているかどうか(isFloor)を はい(true)に変更
isFloor = true;
}
}


これでJumpスクリプトの編集は完了です。
Unityの画面に戻り、Playボタンで動作を確認してみてください。
前回のようにSpaceキーを連打しても、ジャンプし続けるのではなく
地面にいる時だけジャンプができるようになりました。
スクリプトの解説
今回のスクリプトを解説していきます。
まずは、以下のコードの解説からしていきます。
//Spaceキーが押された時 かつ 床に当たっているとき
if (Input.GetKeyDown(KeyCode.Space) && isFloor == true)
前回からの変更点は&& isFloor == trueの部分です。
&&は 左側の条件 かつ 右側の条件のかつという意味です。
今回の場合は、Spaceキーが押されたとき((Input.GetKeyDown(KeyCode.Space))
かつ(&&)
床に当たっているとき(isFloor == true)となります。
次のコード解説です。
//ジャンプして床から離れたので、床に当たっているかどうか(isFloor)を いいえ(false)に変更
isFloor = false;
Spaceキーでジャンプしたら、床から離れているはずなので、
床に当たっているかどうか(isFloor)を いいえ(false)に変更しています。
次は当たり判定部分のコード解説です。
private void OnCollisionEnter(Collision collision)
{
//相手の名前を取得
string name = collision.gameObject.name;
//相手の名前が、Floorだった時
if (name == "Floor")
{
//床に当たっているので、床に当たっているかどうか(isFloor)を はい(true)に変更
isFloor = true;
}
}
長いですが、一つ一つ解説していきます。
private void OnCollisionEnter(Collision collision)はこのC#スクリプトがついているオブジェクト(Playerオブジェクト)と別のオブジェクトが衝突したときにUnityが自動的に呼び出し、{}の中の処理を実行します。
「private void OnCollisionEnter(Collision collision)」のスペルを一文字でも間違うと呼び出してくれないので注意が必要です。
string name = collision.gameObject.name; のcollisionは衝突した相手の情報です。
collision.gameObject.nameと書くと衝突した相手(collision)のオブジェクト(gameObject)の名前(name)を取得できます。
名前はHierarchyビューに表示されているオブジェクトの名前です。

if (name == “Floor”)についてはprivate void OnCollisionEnter(Collision collision)が何と衝突しても{}の中の処理を実行するので、衝突相手の名前が床(Floor)の時だけ処理するように条件を設けています。
条件の中のisFloor = true;は床に当たっているかどうか(isFloor)を はい(true)に変更しています。
Jumpスクリプト全体としては、床に当たっていたらジャンプできるようにする
ジャンプしたら、一度床に当たるまでジャンプできないようにするとなっています。
まとめ
ここまでUnityでの接地判定の作り方を学んできました。
今回は以下のことを覚えていっていただけると嬉しいです。
- 当たり判定に必要なコンポーネントCollider
- private void OnCollisionEnter(Collision collision)はオブジェクトと衝突したときUnityが自動呼び出す。
- private void OnCollisionEnter(Collision collision)のcollisionには衝突した相手の情報が入る
今回のプレイヤーと床の当たり判定以外にも、プレイヤーと壁や弾と敵などのいろいろな場面で、当たり判定を使って試してみてください。
(Written by 流)