Menu
CoddyTech

Đường đua

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 49 trên 60.

Chương này xây dựng một trò chơi đi cảnh 3D. Bạn chạy và nhảy qua các bục lơ lửng, cưỡi một bục trượt đi, chạm vào các điểm kiểm tra để khi ngã bạn không bị đưa về điểm xuất phát, thu thập ngọc được đếm trên màn hình, vượt qua vạch đích để sang màn tiếp theo và cố gắng phá kỷ lục thời gian của mình. Trò chơi có năm script, đã có sẵn trong dự án từ đầu: Player, MovingPlatform, Checkpoint, Gem và FinishLine. Bốn script cuối hiện vẫn để trống, và mỗi bài học sẽ hoàn thiện một script. Nhân vật là một CharacterController được điều khiển bằng các hành động của Input System, còn camera là đối tượng con của nhân vật nên sẽ đi theo mà không cần script.

CharacterController di chuyển theo hai cách. Move(motion) di chuyển nhân vật một khoảng cách và không cộng thêm gì, nên script phải xử lý trọng lực, cú nhảy và Time.deltaTime, như trong chương Character Controller. SimpleMove(speed) nhận tốc độ tính bằng đơn vị mỗi giây, tự nhân tốc độ với thời gian của khung hình và thêm trọng lực; phương thức này bỏ qua giá trị y bạn truyền vào, nên nhân vật di chuyển bằng nó sẽ rơi khỏi mép bục nhưng không thể nhảy. Chú chó chăn cừu trong trò chơi chăn cừu nhìn từ trên cao này không cần nhảy, nên SimpleMove và hành động Move là toàn bộ script của nó:

using UnityEngine;
using UnityEngine.InputSystem;

public class Sheepdog : MonoBehaviour
{
    [SerializeField] private float speed = 6f;
    private CharacterController controller;
    private InputAction moveAction;

    void Start()
    {
        controller = GetComponent<CharacterController>();
        moveAction = InputSystem.actions.FindAction("Move");
    }

    void Update()
    {
        Vector2 input = moveAction.ReadValue<Vector2>();
        controller.SimpleMove(new Vector3(input.x, 0f, input.y) * speed);
    }
}

Nhân vật trong trò chơi đi cảnh cần nhảy, nên tự lưu vận tốc theo chiều dọc và di chuyển bằng Move, đồng thời đọc các hành động Move và Jump thay vì dùng lớp Input. Unity khuyến nghị chỉ gọi Move hoặc SimpleMove một lần mỗi khung hình: gộp bước đi và cú rơi vào cùng một lần gọi, rồi isGrounded sẽ mô tả toàn bộ lần di chuyển đó.

challenge icon

Thử thách

Trung bình

Khiến nhân vật đi bộ, nhảy và rơi.

  1. Trong Start(), tìm Move và Jump bằng InputSystem.actions.FindAction.
  2. Trong Update(), đi bộ với tốc độ speed: x của Move theo trục x, y của nó theo trục z.
  3. Cộng gravity * Time.deltaTime vào velocity.y, đặt thành -2f khi nhân vật đang chạm đất và rơi. Khi đang chạm đất, nhảy sẽ đặt giá trị này thành Mathf.Sqrt(jumpHeight * -2f * gravity).
  4. Gọi controller.Move((move + velocity) * Time.deltaTime) một lần.

Nhấn Chơi: nhảy lên bục đầu tiên. Sau đó nhấn Kiểm tra.

Tự làm thử

using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
    [SerializeField] private float speed = 5f;
    [SerializeField] private float jumpHeight = 1.5f;
    [SerializeField] private float gravity = -9.81f;

    private CharacterController controller;
    private Vector3 velocity;

    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    void Update()
    {
        // Di chuyển bằng hành động Move, nhảy bằng hành động Jump, rơi do trọng lực
    }
}

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