レイを使った接地判定
CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 35/63。
ジャンプは地面からのみ開始できるようにします。Ground に立っている状態は、衝突メッセージによって最新に保たれる接触法線から判定していました。レイを使うと、「何かの上に立っているか」をその場でいつでも判定できます。中心から真下に、中心から底までの距離より少し長くレイを飛ばします。このプレイヤーは高さ 2 units のカプセルなので、底は中心から 1 unit 下にあり、レイの長さは 1.1 です:
public float jumpForce = 5f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && IsGrounded())
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}
bool IsGrounded()
{
return Physics.Raycast(transform.position, Vector3.down, 1.1f);
}追加の 0.1 は余裕分です。床の上で静止している物体は、床からほんの少し浮いたり、床にほんの少しめり込んだりすることがあるため、長さがちょうど 1 のレイではフレームによって検出できません。逆に、長すぎてもよくありません。長さを 3 にすると、プレイヤーは空中で 2 units 上昇した時点で再びジャンプできてしまい、長さが 0 だとレイは常に床を検出するため、ボタンを押すたびにジャンプします。
レイはプレイヤー自身のコライダーの内側から始まりますが、レイはそのようなコライダーを無視するため、プレイヤー自身を検出することはありません。キー入力は Update() で読み取ります。GetKeyDown は 1 フレームだけ true になるためです。また、「インパルスによるジャンプ」の例のように、その場で一度だけインパルスを加えることができます。
チャレンジ
中級Spaceキーを押すたびにカエルがジャンプするため、空中でもジャンプして空高く登ってしまいます。Hopperを修正して、地面にいるときだけジャンプするようにしましょう。
- カエルの中心から真下にレイを飛ばすメソッド
bool IsGrounded()を追加します。カエルはスケールが1.5の球体なので、半径は0.75です。レイがカエルの底からさらに0.1先まで届くようにします。 - Spaceキーが押され、
IsGrounded()がtrueのときだけジャンプするようにします。
再生を押して2回ジャンプしてみてから、確認を押してください。
自分で試してみよう
using UnityEngine;
public class Hopper : MonoBehaviour
{
public float jumpForce = 6f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。