ジャンプ
CoddyのUnityジャーニー「本格的なゲームを作る」セクションの一部。レッスン 39/56。
ジャンプは、Space キーを押した瞬間に一度だけ設定される垂直方向の速度です。スクリプトがすでに加えている重力によって上昇は遅くなり、頂点で止まり、コントローラーは再び下降します。残るのは、所定の高さに達するための初速です。重力は一定の割合で速度を奪うため、速度 v で始まるジャンプは、停止するまでに v * v / (2 * g) 単位上昇します。これを逆にすると、高さ h に達するための初速は v = √(2 * g * h) です。
gravity に負の数 -20 が設定されていて、ジャンプの高さが 2.5 単位の場合、これは Mathf.Sqrt(2.5f * -2f * -20f) となり、100 の平方根、つまり秒速 10 単位です。負の数の平方根は NaN になるため、-2f によって負の重力を正の数にします。
if (controller.isGrounded && verticalSpeed < 0f)
{
verticalSpeed = -2f;
}
if (Input.GetButtonDown("Jump") && controller.isGrounded)
{
verticalSpeed = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
verticalSpeed += gravity * Time.deltaTime;リセットでは verticalSpeed < 0f を判定するため、落下しているときだけ終了します。ジャンプの行の後に単純な if (controller.isGrounded) によるリセットを置くと、ジャンプしたフレームにジャンプ速度が上書きされてしまいます。ジャンプ時の controller.isGrounded の判定によって、空中でのジャンプを防ぎます。Inspector で jumpHeight または gravity を変更しても、ジャンプの高さは正確に jumpHeight に達します。一方、verticalSpeed = 8f のように速度を固定すると、重力ごとに到達する高さが異なります。
チャレンジ
中級2人のジャンパーが同じJumper.csを実行します。Kidはインスペクターでgravityが-18、jumpHeightが1に設定されており、Kangarooはgravityが-8、jumpHeightが4に設定されています。Spaceキーを押すとverticalSpeedが9に設定されますが、この数値は試行錯誤で決められており、どちらのジャンパーにも合わず、空中でも機能してしまいます。ジャンプを修正しましょう。
- Spaceキーを押すとジャンプを開始し、各ジャンパー自身の
jumpHeightとgravityから計算した高さだけ、正確に上昇します。 - 地面にいるジャンパーだけがジャンプできます。
Playを押してジャンプし、それからCheckを押してください。
自分で試してみよう
using UnityEngine;
public class Jumper : MonoBehaviour
{
public float speed = 5f;
public float gravity = -18f;
public float jumpHeight = 1f;
CharacterController controller;
float verticalSpeed;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
if (controller.isGrounded && verticalSpeed < 0f)
{
verticalSpeed = -2f;
}
if (Input.GetButtonDown("Jump"))
{
verticalSpeed = 9f;
}
verticalSpeed += gravity * Time.deltaTime;
Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
move.y = verticalSpeed;
controller.Move(move * Time.deltaTime);
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。