🟢 地面接触判定の実装

Unity

ジャンプを制限する基本的な考え方は、「プレイヤーが地面に触れているかどうか」を常に記録するためのフラグ(旗)となる変数を用意し、ジャンプ実行時にそのフラグをチェックすることです。

1. 準備:地面へのタグ付け

衝突判定を正確に行うために、地面となるオブジェクトに特定のタグを設定します。これにより、壁や天井に触れたときではなく、「地面」に触れたときだけを正確に判定できます。

  1. Hierarchyビューで地面となるオブジェクト(例:PlaneやCube)を選択します。
  2. Inspectorビューの上部にある「Tag」ドロップダウンメニューを開きます。
  3. Add Tag…」を選択し、「+」ボタンを押して新しいタグを作成します。
  4. タグ名に「Ground」と入力して保存します。
  5. 改めて地面オブジェクトを選択し、Tagを「Ground」に設定します。

2. 📝 スクリプトの更新(PlayerMovement.cs)

前回のコードに、新しい変数と、衝突を検出するための特別な関数を追加します。

C#

using UnityEngine;

public class PhysicsMovement : MonoBehaviour
{
    // 公開変数
    public float speed = 500f; 
    public float jumpForce = 500f; 

    // 地面接触判定用のフラグ変数
    private bool isGrounded = false; 
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        // 物理移動の処理 (前回と同じ)
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");
        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        rb.AddForce(movement * speed * Time.fixedDeltaTime);
    }

    // Updateでジャンプ処理 (キー入力の検出)
    void Update()
    {
        // スペースキーが押され、かつ isGroundedがtrueの場合のみ実行
        if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
        {
            // ジャンプ実行
            rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
        }
    }

    // =======================================================
    // 衝突検出の特殊な関数
    // =======================================================
    
    // 他のオブジェクトとの衝突が始まったとき、1回だけ実行される
    void OnCollisionEnter(Collision collision)
    {
        // 衝突した相手のタグが「Ground」であるかチェック
        if (collision.gameObject.CompareTag("Ground"))
        {
            isGrounded = true; // 地面に触れたので、GroundedフラグをONにする
        }
    }

    // 他のオブジェクトとの衝突が終わったとき、1回だけ実行される
    void OnCollisionExit(Collision collision)
    {
        // 離れた相手のタグが「Ground」であるかチェック
        if (collision.gameObject.CompareTag("Ground"))
        {
            isGrounded = false; // 地面から離れたので、GroundedフラグをOFFにする
        }
    }
}

3. 💡 コードの解説

1. private bool isGrounded = false;

  • bool(ブーリアン型)は、true(真)かfalse(偽)のどちらかを取る変数です。初期値はfalse(地面に触れていない)に設定しています。

2. Update()内のジャンプ条件

C#

if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
  • &&(論理積:AND)を使うことで、「スペースキーが押された」と「isGroundedがtrueである」の両方の条件が満たされたときだけジャンプが実行されるようになりました。これで空中での無限ジャンプが制限されます。

3. 衝突開始の検出 (OnCollisionEnter)

C#

void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.CompareTag("Ground"))
    {
        isGrounded = true;
    }
}
  • OnCollisionEnter:プレイヤーオブジェクト(Rigidbody)が他のオブジェクトに衝突した瞬間にUnityが自動的に呼び出す関数です。
  • 引数collisionには衝突した相手の情報が入っています。
  • collision.gameObject.CompareTag("Ground"):衝突した相手のゲームオブジェクトに「Ground」タグが付いているかをチェックしています。付いていればisGroundedtrueにします。

4. 衝突終了の検出 (OnCollisionExit)

C#

void OnCollisionExit(Collision collision)
{
    if (collision.gameObject.CompareTag("Ground"))
    {
        isGrounded = false;
    }
}
  • OnCollisionExit:プレイヤーオブジェクトが他のオブジェクトから離れた瞬間に自動的に呼び出されます。地面から離れる(ジャンプする、落下するなど)とisGroundedfalseに戻します。

実行と確認

このスクリプトを適用した状態でゲームを再生し、スペースキーを連打してみてください。地面にいるときだけジャンプし、空中にいる間はジャンプできないことが確認できるはずです。

コメント