Unityで地面の当たり判定を足元だけ取得する【3D】

今回やること

Rigidbodyによるジャンプの時に地面の当たり判定を足元だけ取得します
コライダーで判定をとる場合、コライダーの下で触れても、上で触れても地面に当たっていることになってしまいます
例えば上下に地面がある場合に、今回のような処理をします

目次

ジャンプするキャラの準備

今回はこちらを参考に準備しました

編集していくスクリプト

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

public class Jump : MonoBehaviour
{
    private Rigidbody rb; // Rigidbodyを使うための変数
    private bool Grounded; // 地面に着地しているか判定する変数
    public float Jumppower; // ジャンプ力

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();//  rbにRigidbodyの値を代入する
    }

    // Update is called once per frame
    void Update()
    {
        print(Grounded);

        if (Input.GetKeyDown(KeyCode.Space))//  もし、スペースキーがおされたなら、  
        {
            if (Grounded == true)//  もし、Groundedがtrueなら、
            {
                Grounded = false;
                rb.AddForce(Vector3.up * Jumppower);//  上にJumpPower分力をかける
            }
        }
    }

    void OnCollisionEnter(Collision other)//  地面に触れた時の処理
    {
        if (other.gameObject.tag == "Ground")//  もしGroundというタグがついたオブジェクトに触れたら、
        {
            Grounded = true;//  Groundedをtrueにする
        }
    }
}

現在はスペースキーをおしたらジャンプできるようになっていますが、地面に触れたかどうかの判定は、コライダーに地面が触れているかどうかで判断しています

画像のように頭が触れていても地面に触れていることになってしまいます

足元だけ地面の判定を取る

今回はRayという機能を使います

Rayとは?
指定された地点から飛ばすレーザー光線のようなもの
当たった物の判定を取ることができる

Jumpスクリプトを編集する

以下のように編集します

編集する内容

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

public class Jump : MonoBehaviour
{
    private Rigidbody rb;
    private bool Grounded;
    public float Jumppower;

    private Ray ray; // 飛ばすレイ
    private float distance = 0.5f; // レイを飛ばす距離
    private RaycastHit hit; // レイが何かに当たった時の情報
    private Vector3 rayPosition; // レイを発射する位置

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        rayPosition = transform.position + new Vector3(0, 0.5f, 0); // レイを発射する位置の調整
        ray = new Ray(rayPosition, transform.up * -1); // レイを下に飛ばす
        Debug.DrawRay(ray.origin, ray.direction * distance, Color.red); // レイを赤色で表示させる
        print(Grounded);

        if (Physics.Raycast(ray, out hit, distance)) // レイが当たった時の処理
        {
            if (hit.collider.tag == "Ground") // レイが地面に触れたら、
            {
                Grounded = true; // 地面に触れたことにする
     
            }

            else // そうでなければ、
            {
                Grounded = false; // 地面に触れてないことにする
             
            }
        }

        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (Grounded == true)
            {
                Grounded = false;
                rb.AddForce(Vector3.up * Jumppower);
            }
        }
    }

    /*ここから
    void OnCollisionEnter(Collision other)
    {
        if (other.gameObject.tag == "Ground")
        {
            Grounded = true;
        }
    }*/ここまで削除する
}

スクリプトの解説

レイを下に飛ばし、レイが地面に触れてるかどうかで、Groundedを切り替えています
コライダーの代わりにレイで判定を取るようにしました

テストプレイをすると

足元が地面に触れてる時だけ地面に触れていることになっています

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次