ジャンプ
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 のように速度を固定すると、重力が変わるたびに到達する高さも変わります。
チャレンジ
中級Kid と Kangaroo の両方に合うジャンプスクリプトを作りましょう。
Update()内で、9fをMathf.Sqrt(jumpHeight * -2f * gravity)に置き換えます。これは、ちょうどjumpHeightだけ上昇するための初速です。- ジャンプの
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プレイグラウンド