ひとりでのアプリ開発 - fineの備忘録 -

ひとりでアプリ開発をするなかで起こったことや学んだことを書き溜めていきます

20220329162023

Unity - 2D:接地判定、AddForceによるジャンプの処理 -

初めに

 プレイヤーが地面に触れているかどうか判定できるようにします。また、transformでのジャンプはどちらかといえば浮遊に近く、違和感があるため、AddForceを用いたジャンプを導入します。


準備

 プレイヤーに当たり判定をつけるため、Rigidbody2D, Collider2Dをつけておきましょう。

 Rigidbody、Colliderについては、下の記事で説明していますので、そちらをご覧ください。

fineworks-fine.hatenablog.com
fineworks-fine.hatenablog.com

 また、キー入力を取得する場面がでてきます。その説明については、下の記事をご覧ください。

fineworks-fine.hatenablog.com

接地判定を作る

 CompareTagを使い、地面に触れているか判定します。

  • 地面のtagを "Groud" に変更する


 初めから "Groud" というtagが用意されているわけではありません。Add Tag をクリックし、"Groud" というtagを追加しましょう。

 プレイヤーのスクリプトに次を追加します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerScript : MonoBehaviour
{
     //接地判定
    private bool isGround = false;

    //何かに触れているときに呼び出される
    void OnCollisionStay2D(Collision2D collision)
    {
      if(collision.collider.CompareTag("Ground"))
      {
        isGround = true;
      }
    }

    //何かから離れたときに呼び出される
    void OnCollisionExit2D(Collision2D collision)
    {
      if(collision.collider.CompareTag("Ground"))
      {
        isGround = false;
      }
    }
}

 CompareTagを使い、触れたオブジェクトのtagが "Groud" か判定しています。触れたオブジェクトのtagが "Groud" ならば isGroud をtrueに、離れたオブジェクトが "Groud" ならば isGroud を false にしています。

この接地判定の注意点

 今回は簡単のために、このような処理をしていますが、このままではプレイヤーの頭や体が地面に触れているときにも "isGroud" がtrueになります。本当に地面に足がついている場合のみを取得したい場合は、プレイヤーの足に空のオブジェクトをつけておき、それに地面が触れているか判定しましょう。

AddForceを使ってジャンプする

 AddForceを使って、プレイヤーに力を加えジャンプさせます。AddForceについての説明は、上にリンク先を載せたRigidbody2Dの記事に載せていますので、割愛します。
 プレイヤーのスクリプトを下のように書き換えます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerScript : MonoBehaviour
{
    //Animatorを入れる変数
    private Animator animator;

    //Rigidbory2D
    private Rigidbody2D rb;
    public float JumpForce = 200f;  //ジャンプ力

    //接地判定
    private bool isGround = false;

    void Start()
    {
      //Animatorを取得
      animator = GetComponent<Animator>();

      //Rigidbody2Dを取得
      rb = this.GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetAxis("Horizontal") > 0)  //HorizontalのPositive Buttonが押されたら
        {
          this.transform.position += new Vector3(0.1f, 0.0f, 0.0f);
          //右を向くためにScaleのx成分を変更
          this.transform.localScale = new Vector3(-0.5f, 0.5f, 0.5f);
          //AnimatorパラメーターのWalkをtrueに
          animator.SetBool("Walk", true);
        }
        else if(Input.GetAxis("Horizontal") < 0)  //HorizontalのNegative Buttonが押されたら
        {
          this.transform.position += new Vector3(-0.1f, 0.0f, 0.0f);
          //左を向くためにScaleのx成分を変更
          this.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
          //AnimatorパラメーターのWalkをtrueに
          animator.SetBool("Walk", true);
        }
        else
        {
          //入力されていないときはWalkをfalseに
          animator.SetBool("Walk", false);
        }

        if(Input.GetAxis("Jump") > 0)  //JumpのPositive Buttonが押されたら
        {
          if(isGround)
          {
            Vector2 force = new Vector2(0, JumpForce);  //y軸方向のみ数値を加える
            rb.AddForce(force);  //ジャンプ

            //AnimatorパラメーターのJumpをtrueに
            animator.SetBool("Jump", true);
          }
        }
        else
        {
          //AnimatorパラメーターのJumpをfalseに
          animator.SetBool("Jump", false);
        }
    }

    void OnCollisionStay2D(Collision2D collision)
    {
      if(collision.collider.CompareTag("Ground"))
      {
        isGround = true;
      }
    }

    void OnCollisionExit2D(Collision2D collision)
    {
      if(collision.collider.CompareTag("Ground"))
      {
        isGround = false;
      }
    }
}

実行結果

 ジャンプ力が変えたい場合は、JunpForceの値を変更しましょう。publicにしているのでInspectorから変更できます。

今回のスクリプトについて

 このスクリプトは以前、Animatorの使い方のときにアニメーションの処理も記入したものになっています。アニメーションをつける場合は、下の記事をご覧ください。いったん、ジャンプの処理だけ作る場合は、"animator" が書いてある部分を削除していただけると、正常に動きます。

fineworks-fine.hatenablog.com
fineworks-fine.hatenablog.com

最後に

 接地判定、AddForceによるジャンプの処理を作りました。いままでの記事で学んだことの復習にもなったのではないでしょうか。