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 个单位。-2f 会将负重力转换为正数,因为负数的平方根是 NaN:

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

挑战

中等

让一份跳跃脚本同时适用于小孩和袋鼠。

  1. 在 Update() 中,将 9f 替换为 Mathf.Sqrt(jumpHeight * -2f * gravity),这是恰好上升 jumpHeight 的起始速度。
  2. 在跳跃的 if 中添加 && controller.isGrounded,这样角色在空中时就不会跳跃。

按“开始”,再按 Space:小孩上升 1 个单位,袋鼠上升 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 在线编辑器