跳跃
本课属于 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 这样的固定速度,在不同重力下会达到不同的高度。
挑战
中等让一份跳跃脚本同时适用于小孩和袋鼠。
- 在
Update()中,将9f替换为Mathf.Sqrt(jumpHeight * -2f * gravity),这是恰好上升jumpHeight的起始速度。 - 在跳跃的
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 在线编辑器