Menu
CoddyTech

ジャンプ

CoddyのUnityジャーニー「本格的なゲームを作る」セクションの一部。レッスン 40/60。

ジャンプとは、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

チャレンジ

中級

Kid と Kangaroo の両方に合うジャンプスクリプトを作りましょう。

  1. Update() 内で、9f を Mathf.Sqrt(jumpHeight * -2f * gravity) に置き換えます。これは、ちょうど jumpHeight だけ上昇するための初速です。
  2. ジャンプの if に && controller.isGrounded を追加し、空中ではジャンプできないようにします。

「プレイ」を押して Space を押します。Kid は 1 単位、Kangaroo は 4 単位上昇します。その後、「確認」を押します。

自分で試してみよう

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);
    }
}

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

自分で練習してみよう: Unityプレイグラウンド