Menu
CoddyTech

ジャンプ

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 のように速度を固定すると、重力ごとに到達する高さが異なります。

challenge icon

チャレンジ

中級

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);
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

本格的なゲームを作るのすべてのレッスン