Menu
CoddyTech

Nhảy

Thuộc phần Xây dựng trò chơi thực tế trong hành trình Unity của Coddy. Bài học 40 trên 60.

Một cú nhảy bắt đầu bằng một tốc độ theo chiều dọc được đặt một lần, ngay lúc bạn nhấn phím cách; trọng lực mà script đã thêm vào sẽ làm chậm đà đi lên, dừng nhân vật ở đỉnh rồi đưa bộ điều khiển trở xuống. Điều còn lại là xác định tốc độ ban đầu để đạt độ cao mong muốn. Trọng lực làm giảm tốc độ đều đặn, vì vậy cú nhảy bắt đầu với tốc độ v sẽ lên cao v * v / (2 * g) đơn vị trước khi dừng lại. Đảo công thức, ta có tốc độ ban đầu để đạt độ cao h là v = √(2 * g * h).

Khi gravity được lưu dưới dạng số âm, -20, và cú nhảy cao 2.5 đơn vị, ta có Mathf.Sqrt(2.5f * -2f * -20f), căn bậc hai của 100: 10 đơn vị mỗi giây. -2f biến trọng lực âm thành số dương, vì căn bậc hai của một số âm là NaN:

if (controller.isGrounded && verticalSpeed < 0f)
{
    verticalSpeed = -2f;
}
if (Input.GetButtonDown("Jump") && controller.isGrounded)
{
    verticalSpeed = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
verticalSpeed += gravity * Time.deltaTime;

Phép kiểm tra đặt lại dùng verticalSpeed < 0f, nên chỉ kết thúc lúc rơi xuống: nếu dùng if (controller.isGrounded) đơn thuần để đặt lại sau dòng lệnh nhảy, tốc độ nhảy sẽ bị ghi đè ngay trong khung hình thực hiện cú nhảy. Phép kiểm tra controller.isGrounded trong câu lệnh nhảy ngăn bạn nhảy giữa không trung. Thay đổi jumpHeight hoặc gravity trong cửa sổ Inspector, cú nhảy vẫn đạt đúng độ cao jumpHeight, còn tốc độ cố định như verticalSpeed = 8f sẽ đạt độ cao khác nhau tùy theo trọng lực.

challenge icon

Thử thách

Trung bình

Viết một tập lệnh nhảy dùng được cho cả Kid và Kangaroo.

  1. Trong Update(), thay 9f bằng Mathf.Sqrt(jumpHeight * -2f * gravity), vận tốc ban đầu giúp nhân vật nhảy lên đúng bằng jumpHeight.
  2. Thêm && controller.isGrounded vào if điều khiển cú nhảy để nhân vật không thể nhảy giữa không trung.

Nhấn nút Chơi rồi nhấn Space: Kid nhảy lên 1 đơn vị, còn Kangaroo nhảy lên 4 đơn vị. Sau đó nhấn nút Kiểm tra.

Tự làm thử

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

Tất cả bài học trong Xây dựng trò chơi thực tế

Tự luyện tập: Playground Unity